fix: resolve ShowDialog scope issue by refactoring event handlers to script-scoped ViewCache lookups
This commit is contained in:
+330
-224
@@ -9,7 +9,13 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
$ScriptDir = if ($PSScriptRoot) {
|
||||||
|
$PSScriptRoot
|
||||||
|
} elseif ($MyInvocation.MyCommand.Path) {
|
||||||
|
Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
} else {
|
||||||
|
(Get-Location).Path
|
||||||
|
}
|
||||||
|
|
||||||
# 1. Load WPF / .NET GUI Assemblies
|
# 1. Load WPF / .NET GUI Assemblies
|
||||||
Add-Type -AssemblyName PresentationFramework
|
Add-Type -AssemblyName PresentationFramework
|
||||||
@@ -111,6 +117,143 @@ if ($txtSystemClock) {
|
|||||||
# View Cache
|
# View Cache
|
||||||
$ViewCache = @{}
|
$ViewCache = @{}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# Robust Script-Scoped Refresh Functions (Directly finds controls from ViewCache)
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
$script:reloadAd = {
|
||||||
|
$v = $ViewCache["AD"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
$grid = $v.FindName("AdUsersGrid")
|
||||||
|
$txtSearch = $v.FindName("TxtAdSearch")
|
||||||
|
$txtStatusMsg = $v.FindName("TxtAdStatusMsg")
|
||||||
|
$txtTotalCount = $v.FindName("TxtAdTotalCount")
|
||||||
|
|
||||||
|
$filter = if ($txtSearch) { $txtSearch.Text } else { "" }
|
||||||
|
$users = Get-ADUserList -Filter $filter -Config $global:AppConfig
|
||||||
|
if ($grid) { $grid.ItemsSource = $users }
|
||||||
|
if ($txtTotalCount) { $txtTotalCount.Text = "총 $($users.Count) 명의 사용자" }
|
||||||
|
if ($txtStatusMsg) {
|
||||||
|
$isLive = ($users.Count -gt 0 -and $users[0].IsLive)
|
||||||
|
$modeText = if ($isLive) { "실제 도메인 컨트롤러 연결 중 ($($global:AppConfig.ActiveDirectory.DomainController))" } else { "데모 시뮬레이션 모드 (config.json에서 실제 연결 설정 가능)" }
|
||||||
|
$txtStatusMsg.Text = "상태: $modeText"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$script:reloadNetApp = {
|
||||||
|
$v = $ViewCache["NetApp"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
$qtreeGrid = $v.FindName("QtreeGrid")
|
||||||
|
$quotaGrid = $v.FindName("QuotaGrid")
|
||||||
|
$shareGrid = $v.FindName("ShareGrid")
|
||||||
|
$txtNetAppStatus = $v.FindName("TxtNetAppStatusMsg")
|
||||||
|
|
||||||
|
$qtrees = Get-NetAppQtrees -Config $global:AppConfig
|
||||||
|
$quotas = Get-NetAppQuotas -Config $global:AppConfig
|
||||||
|
$shares = Get-NetAppShares -Config $global:AppConfig
|
||||||
|
|
||||||
|
if ($qtreeGrid) { $qtreeGrid.ItemsSource = $qtrees }
|
||||||
|
if ($quotaGrid) { $quotaGrid.ItemsSource = $quotas }
|
||||||
|
if ($shareGrid) { $shareGrid.ItemsSource = $shares }
|
||||||
|
|
||||||
|
$isLive = ($qtrees.Count -gt 0 -and $qtrees[0].IsLive)
|
||||||
|
if ($txtNetAppStatus) {
|
||||||
|
$modeText = if ($isLive) { "ONTAP REST API 실시간 연결됨 ($($global:AppConfig.NetApp.ClusterEndpoint))" } else { "데모/시뮬레이션 모드 (ONTAP REST API v2 호환 구조)" }
|
||||||
|
$txtNetAppStatus.Text = "스토리지 응답: $modeText"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$script:reloadShareData = {
|
||||||
|
$v = $ViewCache["ShareAccess"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
$cmb = $v.FindName("CmbShareList")
|
||||||
|
$dbGrid = $v.FindName("DbUsersGrid")
|
||||||
|
$adGrid = $v.FindName("ADGroupMembersGrid")
|
||||||
|
$targetG = $v.FindName("TxtTargetADGroupName")
|
||||||
|
$dbCnt = $v.FindName("TxtDbCount")
|
||||||
|
$adCnt = $v.FindName("TxtAdGroupCount")
|
||||||
|
|
||||||
|
$selectedItem = if ($cmb) { $cmb.SelectedItem } else { $null }
|
||||||
|
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
||||||
|
if ($targetG) { $targetG.Text = $shareName }
|
||||||
|
|
||||||
|
$dbUsers = Get-DbUsersForShare -ShareName $shareName -Config $global:AppConfig
|
||||||
|
if ($dbGrid) { $dbGrid.ItemsSource = $dbUsers }
|
||||||
|
if ($dbCnt) { $dbCnt.Text = "총 $($dbUsers.Count)명 조회됨" }
|
||||||
|
|
||||||
|
$adMembers = Get-ADGroupMembersByShareName -GroupName $shareName -Config $global:AppConfig
|
||||||
|
if ($adGrid) { $adGrid.ItemsSource = $adMembers }
|
||||||
|
if ($adCnt) { $adCnt.Text = "현재 그룹 멤버: $($adMembers.Count)명" }
|
||||||
|
}
|
||||||
|
|
||||||
|
$script:reloadSql = {
|
||||||
|
$v = $ViewCache["Sql"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
$dbGrid = $v.FindName("SqlDbGrid")
|
||||||
|
$txtSqlStatusMsg = $v.FindName("TxtSqlStatusMsg")
|
||||||
|
$txtSqlTotalCount = $v.FindName("TxtSqlTotalCount")
|
||||||
|
|
||||||
|
$dbs = Get-SqlDatabases -Config $global:AppConfig
|
||||||
|
if ($dbGrid) { $dbGrid.ItemsSource = $dbs }
|
||||||
|
if ($txtSqlTotalCount) { $txtSqlTotalCount.Text = "총 $($dbs.Count)개 데이터베이스" }
|
||||||
|
if ($txtSqlStatusMsg) {
|
||||||
|
$isLive = ($dbs.Count -gt 0 -and $dbs[0].IsLive)
|
||||||
|
$modeText = if ($isLive) { "실제 SQL Server 연결 ($($global:AppConfig.MsSql.Server))" } else { "데모/시뮬레이션 모드 (System.Data.SqlClient 연동 완비)" }
|
||||||
|
$txtSqlStatusMsg.Text = "상태: $modeText"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$script:loadSettingsToUI = {
|
||||||
|
$v = $ViewCache["Settings"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
|
||||||
|
$chkGlobalLive = $v.FindName("ChkGlobalLiveMode")
|
||||||
|
$chkAdLive = $v.FindName("ChkAdLive")
|
||||||
|
$txtAdDc = $v.FindName("TxtAdDc")
|
||||||
|
$txtAdBaseOu = $v.FindName("TxtAdBaseOu")
|
||||||
|
$chkAdLdaps = $v.FindName("ChkAdLdaps")
|
||||||
|
$txtAdUser = $v.FindName("TxtAdUser")
|
||||||
|
$txtAdPassword = $v.FindName("TxtAdPassword")
|
||||||
|
|
||||||
|
$chkNetAppLive = $v.FindName("ChkNetAppLive")
|
||||||
|
$txtNetAppEndpoint = $v.FindName("TxtNetAppEndpoint")
|
||||||
|
$txtNetAppDefaultSvm = $v.FindName("TxtNetAppDefaultSvm")
|
||||||
|
$chkNetAppIgnoreSsl = $v.FindName("ChkNetAppIgnoreSsl")
|
||||||
|
$txtNetAppUser = $v.FindName("TxtNetAppUser")
|
||||||
|
$txtNetAppPassword = $v.FindName("TxtNetAppPassword")
|
||||||
|
|
||||||
|
$chkSqlLive = $v.FindName("ChkSqlLive")
|
||||||
|
$txtSqlServer = $v.FindName("TxtSqlServer")
|
||||||
|
$cmbSqlAuth = $v.FindName("CmbSqlAuthType")
|
||||||
|
$txtSqlBackupDir = $v.FindName("TxtSqlBackupDir")
|
||||||
|
$txtSqlUser = $v.FindName("TxtSqlUser")
|
||||||
|
$txtSqlPassword = $v.FindName("TxtSqlPassword")
|
||||||
|
|
||||||
|
$c = $global:AppConfig
|
||||||
|
if ($chkGlobalLive) { $chkGlobalLive.IsChecked = [bool]$c.Application.LiveMode }
|
||||||
|
|
||||||
|
if ($chkAdLive) { $chkAdLive.IsChecked = [bool]$c.ActiveDirectory.UseLive }
|
||||||
|
if ($txtAdDc) { $txtAdDc.Text = $c.ActiveDirectory.DomainController }
|
||||||
|
if ($txtAdBaseOu) { $txtAdBaseOu.Text = $c.ActiveDirectory.BaseOU }
|
||||||
|
if ($chkAdLdaps) { $chkAdLdaps.IsChecked = [bool]$c.ActiveDirectory.UseLdaps }
|
||||||
|
if ($txtAdUser) { $txtAdUser.Text = $c.ActiveDirectory.Username }
|
||||||
|
if ($txtAdPassword) { $txtAdPassword.Password = $c.ActiveDirectory.Password }
|
||||||
|
|
||||||
|
if ($chkNetAppLive) { $chkNetAppLive.IsChecked = [bool]$c.NetApp.UseLive }
|
||||||
|
if ($txtNetAppEndpoint) { $txtNetAppEndpoint.Text = $c.NetApp.ClusterEndpoint }
|
||||||
|
if ($txtNetAppDefaultSvm) { $txtNetAppDefaultSvm.Text = $c.NetApp.DefaultSvm }
|
||||||
|
if ($chkNetAppIgnoreSsl) { $chkNetAppIgnoreSsl.IsChecked = [bool]$c.NetApp.IgnoreSslErrors }
|
||||||
|
if ($txtNetAppUser) { $txtNetAppUser.Text = $c.NetApp.Username }
|
||||||
|
if ($txtNetAppPassword) { $txtNetAppPassword.Password = $c.NetApp.Password }
|
||||||
|
|
||||||
|
if ($chkSqlLive) { $chkSqlLive.IsChecked = [bool]$c.MsSql.UseLive }
|
||||||
|
if ($txtSqlServer) { $txtSqlServer.Text = $c.MsSql.Server }
|
||||||
|
if ($cmbSqlAuth) { $cmbSqlAuth.SelectedIndex = if ($c.MsSql.AuthType -eq "Sql") { 1 } else { 0 } }
|
||||||
|
if ($txtSqlBackupDir) { $txtSqlBackupDir.Text = $c.MsSql.BackupDirectory }
|
||||||
|
if ($txtSqlUser) { $txtSqlUser.Text = $c.MsSql.Username }
|
||||||
|
if ($txtSqlPassword) { $txtSqlPassword.Password = $c.MsSql.Password }
|
||||||
|
}
|
||||||
|
|
||||||
# Function to Switch Navigation Pages
|
# Function to Switch Navigation Pages
|
||||||
function Navigate-ToPage {
|
function Navigate-ToPage {
|
||||||
param([string]$PageName)
|
param([string]$PageName)
|
||||||
@@ -139,7 +282,7 @@ function Navigate-ToPage {
|
|||||||
$quickQuota = $view.FindName("QuickBtnQuota")
|
$quickQuota = $view.FindName("QuickBtnQuota")
|
||||||
if ($quickQuota) { $quickQuota.add_Click({ $navNetApp.IsChecked = $true }) }
|
if ($quickQuota) { $quickQuota.add_Click({ $navNetApp.IsChecked = $true }) }
|
||||||
$quickShare = $view.FindName("QuickBtnShare")
|
$quickShare = $view.FindName("QuickBtnShare")
|
||||||
if ($quickShare) { $quickShare.add_Click({ $navNetApp.IsChecked = $true }) }
|
if ($quickShare) { $quickShare.add_Click({ $navShareAccess.IsChecked = $true }) }
|
||||||
$quickSql = $view.FindName("QuickBtnSql")
|
$quickSql = $view.FindName("QuickBtnSql")
|
||||||
if ($quickSql) { $quickSql.add_Click({ $navSql.IsChecked = $true }) }
|
if ($quickSql) { $quickSql.add_Click({ $navSql.IsChecked = $true }) }
|
||||||
|
|
||||||
@@ -154,16 +297,14 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if (-not $ViewCache.ContainsKey("AD")) {
|
if (-not $ViewCache.ContainsKey("AD")) {
|
||||||
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\ActiveDirectoryView.xaml")
|
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\ActiveDirectoryView.xaml")
|
||||||
|
$ViewCache["AD"] = $view
|
||||||
|
|
||||||
$grid = $view.FindName("AdUsersGrid")
|
$grid = $view.FindName("AdUsersGrid")
|
||||||
$txtSearch = $view.FindName("TxtAdSearch")
|
|
||||||
$btnSearch = $view.FindName("BtnAdSearch")
|
$btnSearch = $view.FindName("BtnAdSearch")
|
||||||
$btnRefresh = $view.FindName("BtnAdRefresh")
|
$btnRefresh = $view.FindName("BtnAdRefresh")
|
||||||
$btnUnlock = $view.FindName("BtnAdUnlock")
|
$btnUnlock = $view.FindName("BtnAdUnlock")
|
||||||
$btnResetPwd = $view.FindName("BtnAdResetPwd")
|
$btnResetPwd = $view.FindName("BtnAdResetPwd")
|
||||||
$btnToggleEnable = $view.FindName("BtnAdToggleEnable")
|
$btnToggleEnable = $view.FindName("BtnAdToggleEnable")
|
||||||
$txtStatusMsg = $view.FindName("TxtAdStatusMsg")
|
|
||||||
$txtTotalCount = $view.FindName("TxtAdTotalCount")
|
|
||||||
|
|
||||||
$txtDetailName = $view.FindName("TxtDetailName")
|
$txtDetailName = $view.FindName("TxtDetailName")
|
||||||
$txtDetailEmail = $view.FindName("TxtDetailEmail")
|
$txtDetailEmail = $view.FindName("TxtDetailEmail")
|
||||||
@@ -171,36 +312,30 @@ function Navigate-ToPage {
|
|||||||
$txtPropStatus = $view.FindName("TxtPropStatus")
|
$txtPropStatus = $view.FindName("TxtPropStatus")
|
||||||
$listGroups = $view.FindName("ListMemberGroups")
|
$listGroups = $view.FindName("ListMemberGroups")
|
||||||
|
|
||||||
$reloadAd = {
|
if ($btnSearch) { $btnSearch.add_Click({ & $script:reloadAd }) }
|
||||||
$filter = if ($txtSearch) { $txtSearch.Text } else { "" }
|
if ($btnRefresh) { $btnRefresh.add_Click({ & $script:reloadAd }) }
|
||||||
$users = Get-ADUserList -Filter $filter -Config $global:AppConfig
|
|
||||||
$grid.ItemsSource = $users
|
|
||||||
if ($txtTotalCount) { $txtTotalCount.Text = "총 $($users.Count) 명의 사용자" }
|
|
||||||
if ($txtStatusMsg) {
|
|
||||||
$isLive = ($users.Count -gt 0 -and $users[0].IsLive)
|
|
||||||
$modeText = if ($isLive) { "실제 도메인 컨트롤러 연결 중 ($($global:AppConfig.ActiveDirectory.DomainController))" } else { "데모 시뮬레이션 모드 (config.json에서 실제 연결 설정 가능)" }
|
|
||||||
$txtStatusMsg.Text = "상태: $modeText"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($btnSearch) { $btnSearch.add_Click($reloadAd) }
|
|
||||||
if ($btnRefresh) { $btnRefresh.add_Click($reloadAd) }
|
|
||||||
|
|
||||||
if ($grid) {
|
if ($grid) {
|
||||||
$grid.add_SelectionChanged({
|
$grid.add_SelectionChanged({
|
||||||
$selected = $grid.SelectedItem
|
$v = $ViewCache["AD"]
|
||||||
|
if (-not $v) { return }
|
||||||
|
$g = $v.FindName("AdUsersGrid")
|
||||||
|
$selected = if ($g) { $g.SelectedItem } else { $null }
|
||||||
if ($selected) {
|
if ($selected) {
|
||||||
$txtDetailName.Text = "$($selected.DisplayName) ($($selected.SamAccountName))"
|
$dn = $v.FindName("TxtDetailName"); if ($dn) { $dn.Text = "$($selected.DisplayName) ($($selected.SamAccountName))" }
|
||||||
$txtDetailEmail.Text = $selected.UserPrincipalName
|
$de = $v.FindName("TxtDetailEmail"); if ($de) { $de.Text = $selected.UserPrincipalName }
|
||||||
$txtDetailOu.Text = $selected.DistinguishedName
|
$do = $v.FindName("TxtDetailOu"); if ($do) { $do.Text = $selected.DistinguishedName }
|
||||||
$txtPropStatus.Text = "$($selected.StatusText) (Locked: $($selected.LockedText))"
|
$ds = $v.FindName("TxtPropStatus"); if ($ds) { $ds.Text = "$($selected.StatusText) (Locked: $($selected.LockedText))" }
|
||||||
|
|
||||||
$listGroups.Items.Clear()
|
$lg = $v.FindName("ListMemberGroups")
|
||||||
$listGroups.Items.Add("Domain Users") | Out-Null
|
if ($lg) {
|
||||||
$listGroups.Items.Add("Remote Desktop Users") | Out-Null
|
$lg.Items.Clear()
|
||||||
if ($selected.Department -like "*인프라*" -or $selected.Department -like "*시스템*") {
|
$lg.Items.Add("Domain Users") | Out-Null
|
||||||
$listGroups.Items.Add("Storage-Admins") | Out-Null
|
$lg.Items.Add("Remote Desktop Users") | Out-Null
|
||||||
$listGroups.Items.Add("Server-Operators") | Out-Null
|
if ($selected.Department -like "*인프라*" -or $selected.Department -like "*시스템*") {
|
||||||
|
$lg.Items.Add("Storage-Admins") | Out-Null
|
||||||
|
$lg.Items.Add("Server-Operators") | Out-Null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -208,11 +343,13 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if ($btnUnlock) {
|
if ($btnUnlock) {
|
||||||
$btnUnlock.add_Click({
|
$btnUnlock.add_Click({
|
||||||
$selected = $grid.SelectedItem
|
$v = $ViewCache["AD"]
|
||||||
|
$g = $v.FindName("AdUsersGrid")
|
||||||
|
$selected = if ($g) { $g.SelectedItem } else { $null }
|
||||||
if ($selected) {
|
if ($selected) {
|
||||||
$res = Unlock-ADUserAccount -SamAccountName $selected.SamAccountName -Config $global:AppConfig
|
$res = Unlock-ADUserAccount -SamAccountName $selected.SamAccountName -Config $global:AppConfig
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "AD 잠금 해제", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "AD 잠금 해제", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
&$reloadAd
|
& $script:reloadAd
|
||||||
} else {
|
} else {
|
||||||
[System.Windows.MessageBox]::Show("목록에서 잠금 해제할 사용자를 선택하십시오.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show("목록에서 잠금 해제할 사용자를 선택하십시오.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
}
|
}
|
||||||
@@ -221,7 +358,9 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if ($btnResetPwd) {
|
if ($btnResetPwd) {
|
||||||
$btnResetPwd.add_Click({
|
$btnResetPwd.add_Click({
|
||||||
$selected = $grid.SelectedItem
|
$v = $ViewCache["AD"]
|
||||||
|
$g = $v.FindName("AdUsersGrid")
|
||||||
|
$selected = if ($g) { $g.SelectedItem } else { $null }
|
||||||
if ($selected) {
|
if ($selected) {
|
||||||
$res = Reset-ADUserPassword -SamAccountName $selected.SamAccountName -Config $global:AppConfig
|
$res = Reset-ADUserPassword -SamAccountName $selected.SamAccountName -Config $global:AppConfig
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "AD 암호 초기화", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "AD 암호 초기화", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
@@ -233,20 +372,21 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if ($btnToggleEnable) {
|
if ($btnToggleEnable) {
|
||||||
$btnToggleEnable.add_Click({
|
$btnToggleEnable.add_Click({
|
||||||
$selected = $grid.SelectedItem
|
$v = $ViewCache["AD"]
|
||||||
|
$g = $v.FindName("AdUsersGrid")
|
||||||
|
$selected = if ($g) { $g.SelectedItem } else { $null }
|
||||||
if ($selected) {
|
if ($selected) {
|
||||||
$newState = (-not $selected.Enabled)
|
$newState = (-not $selected.Enabled)
|
||||||
$res = Set-ADUserAccountState -SamAccountName $selected.SamAccountName -Enable $newState -Config $global:AppConfig
|
$res = Set-ADUserAccountState -SamAccountName $selected.SamAccountName -Enable $newState -Config $global:AppConfig
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "AD 계정 상태 전환", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "AD 계정 상태 전환", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
&$reloadAd
|
& $script:reloadAd
|
||||||
} else {
|
} else {
|
||||||
[System.Windows.MessageBox]::Show("목록에서 사용자를 선택하십시오.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show("목록에서 사용자를 선택하십시오.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
&$reloadAd
|
& $script:reloadAd
|
||||||
$ViewCache["AD"] = $view
|
|
||||||
}
|
}
|
||||||
$mainContentHost.Content = $ViewCache["AD"]
|
$mainContentHost.Content = $ViewCache["AD"]
|
||||||
}
|
}
|
||||||
@@ -257,38 +397,19 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if (-not $ViewCache.ContainsKey("NetApp")) {
|
if (-not $ViewCache.ContainsKey("NetApp")) {
|
||||||
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\NetAppView.xaml")
|
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\NetAppView.xaml")
|
||||||
|
$ViewCache["NetApp"] = $view
|
||||||
$qtreeGrid = $view.FindName("QtreeGrid")
|
|
||||||
$quotaGrid = $view.FindName("QuotaGrid")
|
|
||||||
$shareGrid = $view.FindName("ShareGrid")
|
|
||||||
$btnRefreshStorage = $view.FindName("BtnRefreshStorage")
|
$btnRefreshStorage = $view.FindName("BtnRefreshStorage")
|
||||||
$btnNewQtree = $view.FindName("BtnNewQtree")
|
$btnNewQtree = $view.FindName("BtnNewQtree")
|
||||||
$btnNewShare = $view.FindName("BtnNewShare")
|
$btnNewShare = $view.FindName("BtnNewShare")
|
||||||
$txtNetAppStatus = $view.FindName("TxtNetAppStatusMsg")
|
|
||||||
|
|
||||||
$reloadNetApp = {
|
if ($btnRefreshStorage) { $btnRefreshStorage.add_Click({ & $script:reloadNetApp }) }
|
||||||
$qtrees = Get-NetAppQtrees -Config $global:AppConfig
|
|
||||||
$quotas = Get-NetAppQuotas -Config $global:AppConfig
|
|
||||||
$shares = Get-NetAppShares -Config $global:AppConfig
|
|
||||||
|
|
||||||
if ($qtreeGrid) { $qtreeGrid.ItemsSource = $qtrees }
|
|
||||||
if ($quotaGrid) { $quotaGrid.ItemsSource = $quotas }
|
|
||||||
if ($shareGrid) { $shareGrid.ItemsSource = $shares }
|
|
||||||
|
|
||||||
$isLive = ($qtrees.Count -gt 0 -and $qtrees[0].IsLive)
|
|
||||||
if ($txtNetAppStatus) {
|
|
||||||
$modeText = if ($isLive) { "ONTAP REST API 실시간 연결됨 ($($global:AppConfig.NetApp.ClusterEndpoint))" } else { "데모/시뮬레이션 모드 (ONTAP REST API v2 호환 구조)" }
|
|
||||||
$txtNetAppStatus.Text = "스토리지 응답: $modeText"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($btnRefreshStorage) { $btnRefreshStorage.add_Click($reloadNetApp) }
|
|
||||||
|
|
||||||
if ($btnNewQtree) {
|
if ($btnNewQtree) {
|
||||||
$btnNewQtree.add_Click({
|
$btnNewQtree.add_Click({
|
||||||
$res = New-NetAppQtreeAction -Volume "vol_cifs_share01" -QtreeName "qtree_new_$((Get-Date).ToString('MMdd_HHmm'))" -Config $global:AppConfig
|
$res = New-NetAppQtreeAction -Volume "vol_cifs_share01" -QtreeName "qtree_new_$((Get-Date).ToString('MMdd_HHmm'))" -Config $global:AppConfig
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "NetApp Qtree 생성", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "NetApp Qtree 생성", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
&$reloadNetApp
|
& $script:reloadNetApp
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,12 +418,11 @@ function Navigate-ToPage {
|
|||||||
$shareName = "Share_$((Get-Date).ToString('MMdd_HHmm'))"
|
$shareName = "Share_$((Get-Date).ToString('MMdd_HHmm'))"
|
||||||
$res = New-NetAppShareAction -ShareName $shareName -Path "/vol/vol_cifs_share01/$shareName" -Comment "관리 도구 생성 공유" -Config $global:AppConfig
|
$res = New-NetAppShareAction -ShareName $shareName -Path "/vol/vol_cifs_share01/$shareName" -Comment "관리 도구 생성 공유" -Config $global:AppConfig
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "NetApp CIFS 공유 생성", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "NetApp CIFS 공유 생성", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
&$reloadNetApp
|
& $script:reloadNetApp
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
&$reloadNetApp
|
& $script:reloadNetApp
|
||||||
$ViewCache["NetApp"] = $view
|
|
||||||
}
|
}
|
||||||
$mainContentHost.Content = $ViewCache["NetApp"]
|
$mainContentHost.Content = $ViewCache["NetApp"]
|
||||||
}
|
}
|
||||||
@@ -313,80 +433,68 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if (-not $ViewCache.ContainsKey("ShareAccess")) {
|
if (-not $ViewCache.ContainsKey("ShareAccess")) {
|
||||||
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\ShareAccessManagerView.xaml")
|
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\ShareAccessManagerView.xaml")
|
||||||
|
$ViewCache["ShareAccess"] = $view
|
||||||
|
|
||||||
$cmbShare = $view.FindName("CmbShareList")
|
$cmbShare = $view.FindName("CmbShareList")
|
||||||
$btnReloadDb = $view.FindName("BtnReloadFromDb")
|
$btnReloadDb = $view.FindName("BtnReloadFromDb")
|
||||||
$btnReloadAd = $view.FindName("BtnReloadADGroup")
|
$btnReloadAd = $view.FindName("BtnReloadADGroup")
|
||||||
$txtTargetGroup = $view.FindName("TxtTargetADGroupName")
|
|
||||||
|
|
||||||
$dbGrid = $view.FindName("DbUsersGrid")
|
|
||||||
$btnSelectAll = $view.FindName("BtnSelectAll")
|
$btnSelectAll = $view.FindName("BtnSelectAll")
|
||||||
$btnDeselectAll = $view.FindName("BtnDeselectAll")
|
$btnDeselectAll = $view.FindName("BtnDeselectAll")
|
||||||
$txtDbCount = $view.FindName("TxtDbCount")
|
|
||||||
|
|
||||||
$btnAdd = $view.FindName("BtnAddToShareGroup")
|
$btnAdd = $view.FindName("BtnAddToShareGroup")
|
||||||
$btnRemove = $view.FindName("BtnRemoveFromShareGroup")
|
$btnRemove = $view.FindName("BtnRemoveFromShareGroup")
|
||||||
|
|
||||||
$adGrid = $view.FindName("ADGroupMembersGrid")
|
|
||||||
$txtAdCount = $view.FindName("TxtAdGroupCount")
|
|
||||||
|
|
||||||
$txtLogs = $view.FindName("TxtSyncLogs")
|
|
||||||
$btnClearLog = $view.FindName("BtnClearLog")
|
$btnClearLog = $view.FindName("BtnClearLog")
|
||||||
|
|
||||||
# Helper to append logs
|
# Helper to append logs
|
||||||
$appendLog = {
|
$appendShareLog = {
|
||||||
param([string]$msg)
|
param([string]$msg)
|
||||||
$time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
|
$v = $ViewCache["ShareAccess"]
|
||||||
$txtLogs.Text = "[$time] $msg`r`n" + $txtLogs.Text
|
if ($v) {
|
||||||
|
$tl = $v.FindName("TxtSyncLogs")
|
||||||
|
if ($tl) {
|
||||||
|
$time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
$tl.Text = "[$time] $msg`r`n" + $tl.Text
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load Share List into ComboBox
|
# Load Share List into ComboBox
|
||||||
$shares = Get-DbShareList -Config $global:AppConfig
|
$shares = Get-DbShareList -Config $global:AppConfig
|
||||||
$cmbShare.Items.Clear()
|
if ($cmbShare) {
|
||||||
foreach ($s in $shares) {
|
$cmbShare.Items.Clear()
|
||||||
$item = New-Object System.Windows.Controls.ComboBoxItem
|
foreach ($s in $shares) {
|
||||||
$item.Content = "$($s.ShareName) ($($s.Description))"
|
$item = New-Object System.Windows.Controls.ComboBoxItem
|
||||||
$item.Tag = $s.ShareName
|
$item.Content = "$($s.ShareName) ($($s.Description))"
|
||||||
$cmbShare.Items.Add($item) | Out-Null
|
$item.Tag = $s.ShareName
|
||||||
}
|
$cmbShare.Items.Add($item) | Out-Null
|
||||||
if ($cmbShare.Items.Count -gt 0) { $cmbShare.SelectedIndex = 0 }
|
}
|
||||||
|
|
||||||
# Function to reload DB and AD members for current Share
|
$cmbShare.add_SelectionChanged({ & $script:reloadShareData })
|
||||||
$reloadShareData = {
|
|
||||||
$selectedItem = $cmbShare.SelectedItem
|
|
||||||
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
|
||||||
if ($txtTargetGroup) { $txtTargetGroup.Text = $shareName }
|
|
||||||
|
|
||||||
# 1. DB Users
|
|
||||||
$dbUsers = Get-DbUsersForShare -ShareName $shareName -Config $global:AppConfig
|
|
||||||
$dbGrid.ItemsSource = $dbUsers
|
|
||||||
if ($txtDbCount) { $txtDbCount.Text = "총 $($dbUsers.Count)명 조회됨" }
|
|
||||||
|
|
||||||
# 2. AD Group Members
|
|
||||||
$adMembers = Get-ADGroupMembersByShareName -GroupName $shareName -Config $global:AppConfig
|
|
||||||
$adGrid.ItemsSource = $adMembers
|
|
||||||
if ($txtAdCount) { $txtAdCount.Text = "현재 그룹 멤버: $($adMembers.Count)명" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$cmbShare.add_SelectionChanged({ &$reloadShareData })
|
if ($btnReloadDb) { $btnReloadDb.add_Click({ & $script:reloadShareData }) }
|
||||||
if ($btnReloadDb) { $btnReloadDb.add_Click({ &$reloadShareData }) }
|
if ($btnReloadAd) { $btnReloadAd.add_Click({ & $script:reloadShareData }) }
|
||||||
if ($btnReloadAd) { $btnReloadAd.add_Click({ &$reloadShareData }) }
|
|
||||||
|
|
||||||
# Select / Deselect All
|
# Select / Deselect All
|
||||||
if ($btnSelectAll) {
|
if ($btnSelectAll) {
|
||||||
$btnSelectAll.add_Click({
|
$btnSelectAll.add_Click({
|
||||||
if ($dbGrid.ItemsSource) {
|
$v = $ViewCache["ShareAccess"]
|
||||||
foreach ($u in $dbGrid.ItemsSource) { $u.IsSelected = $true }
|
$g = $v.FindName("DbUsersGrid")
|
||||||
$dbGrid.Items.Refresh()
|
if ($g -and $g.ItemsSource) {
|
||||||
|
foreach ($u in $g.ItemsSource) { $u.IsSelected = $true }
|
||||||
|
$g.Items.Refresh()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($btnDeselectAll) {
|
if ($btnDeselectAll) {
|
||||||
$btnDeselectAll.add_Click({
|
$btnDeselectAll.add_Click({
|
||||||
if ($dbGrid.ItemsSource) {
|
$v = $ViewCache["ShareAccess"]
|
||||||
foreach ($u in $dbGrid.ItemsSource) { $u.IsSelected = $false }
|
$g = $v.FindName("DbUsersGrid")
|
||||||
$dbGrid.Items.Refresh()
|
if ($g -and $g.ItemsSource) {
|
||||||
|
foreach ($u in $g.ItemsSource) { $u.IsSelected = $false }
|
||||||
|
$g.Items.Refresh()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -394,10 +502,14 @@ function Navigate-ToPage {
|
|||||||
# Action: Add Users to Share Group
|
# Action: Add Users to Share Group
|
||||||
if ($btnAdd) {
|
if ($btnAdd) {
|
||||||
$btnAdd.add_Click({
|
$btnAdd.add_Click({
|
||||||
$selectedItem = $cmbShare.SelectedItem
|
$v = $ViewCache["ShareAccess"]
|
||||||
|
$cmb = $v.FindName("CmbShareList")
|
||||||
|
$g = $v.FindName("DbUsersGrid")
|
||||||
|
|
||||||
|
$selectedItem = if ($cmb) { $cmb.SelectedItem } else { $null }
|
||||||
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
||||||
|
|
||||||
$checkedUsers = @($dbGrid.ItemsSource | Where-Object { $_.IsSelected })
|
$checkedUsers = if ($g -and $g.ItemsSource) { @($g.ItemsSource | Where-Object { $_.IsSelected }) } else { @() }
|
||||||
if ($checkedUsers.Count -eq 0) {
|
if ($checkedUsers.Count -eq 0) {
|
||||||
[System.Windows.MessageBox]::Show("목록에서 추가할 사용자를 체크박스로 1명 이상 선택하십시오.", "선택 필요", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show("목록에서 추가할 사용자를 체크박스로 1명 이상 선택하십시오.", "선택 필요", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
@@ -406,20 +518,24 @@ function Navigate-ToPage {
|
|||||||
$sams = @($checkedUsers | ForEach-Object { $_.SamAccountName })
|
$sams = @($checkedUsers | ForEach-Object { $_.SamAccountName })
|
||||||
$res = Add-UsersToShareAndGroup -ShareName $shareName -SamAccountNames $sams -Config $global:AppConfig
|
$res = Add-UsersToShareAndGroup -ShareName $shareName -SamAccountNames $sams -Config $global:AppConfig
|
||||||
|
|
||||||
foreach ($l in $res.Logs) { &$appendLog $l }
|
foreach ($l in $res.Logs) { & $appendShareLog $l }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "그룹 추가 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "그룹 추가 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
|
|
||||||
&$reloadShareData
|
& $script:reloadShareData
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
# Action: Remove Users from Share Group
|
# Action: Remove Users from Share Group
|
||||||
if ($btnRemove) {
|
if ($btnRemove) {
|
||||||
$btnRemove.add_Click({
|
$btnRemove.add_Click({
|
||||||
$selectedItem = $cmbShare.SelectedItem
|
$v = $ViewCache["ShareAccess"]
|
||||||
|
$cmb = $v.FindName("CmbShareList")
|
||||||
|
$g = $v.FindName("DbUsersGrid")
|
||||||
|
|
||||||
|
$selectedItem = if ($cmb) { $cmb.SelectedItem } else { $null }
|
||||||
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
$shareName = if ($selectedItem -and $selectedItem.Tag) { $selectedItem.Tag } else { "Finance_Share" }
|
||||||
|
|
||||||
$checkedUsers = @($dbGrid.ItemsSource | Where-Object { $_.IsSelected })
|
$checkedUsers = if ($g -and $g.ItemsSource) { @($g.ItemsSource | Where-Object { $_.IsSelected }) } else { @() }
|
||||||
if ($checkedUsers.Count -eq 0) {
|
if ($checkedUsers.Count -eq 0) {
|
||||||
[System.Windows.MessageBox]::Show("목록에서 해제/제거할 사용자를 체크박스로 1명 이상 선택하십시오.", "선택 필요", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show("목록에서 해제/제거할 사용자를 체크박스로 1명 이상 선택하십시오.", "선택 필요", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
@@ -428,19 +544,27 @@ function Navigate-ToPage {
|
|||||||
$sams = @($checkedUsers | ForEach-Object { $_.SamAccountName })
|
$sams = @($checkedUsers | ForEach-Object { $_.SamAccountName })
|
||||||
$res = Remove-UsersFromShareAndGroup -ShareName $shareName -SamAccountNames $sams -Config $global:AppConfig
|
$res = Remove-UsersFromShareAndGroup -ShareName $shareName -SamAccountNames $sams -Config $global:AppConfig
|
||||||
|
|
||||||
foreach ($l in $res.Logs) { &$appendLog $l }
|
foreach ($l in $res.Logs) { & $appendShareLog $l }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "그룹 해제 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show($res.Message, "그룹 해제 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
|
|
||||||
&$reloadShareData
|
& $script:reloadShareData
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($btnClearLog) {
|
if ($btnClearLog) {
|
||||||
$btnClearLog.add_Click({ $txtLogs.Text = "" })
|
$btnClearLog.add_Click({
|
||||||
|
$v = $ViewCache["ShareAccess"]
|
||||||
|
$tl = $v.FindName("TxtSyncLogs")
|
||||||
|
if ($tl) { $tl.Text = "" }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
&$reloadShareData
|
# Initial Select
|
||||||
$ViewCache["ShareAccess"] = $view
|
if ($cmbShare -and $cmbShare.Items.Count -gt 0) {
|
||||||
|
$cmbShare.SelectedIndex = 0
|
||||||
|
} else {
|
||||||
|
& $script:reloadShareData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$mainContentHost.Content = $ViewCache["ShareAccess"]
|
$mainContentHost.Content = $ViewCache["ShareAccess"]
|
||||||
}
|
}
|
||||||
@@ -451,29 +575,14 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if (-not $ViewCache.ContainsKey("Sql")) {
|
if (-not $ViewCache.ContainsKey("Sql")) {
|
||||||
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\SqlDatabaseView.xaml")
|
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\SqlDatabaseView.xaml")
|
||||||
|
$ViewCache["Sql"] = $view
|
||||||
$dbGrid = $view.FindName("SqlDbGrid")
|
|
||||||
$btnSqlRefresh = $view.FindName("BtnSqlRefresh")
|
$btnSqlRefresh = $view.FindName("BtnSqlRefresh")
|
||||||
$btnTestConn = $view.FindName("BtnTestSqlConnection")
|
$btnTestConn = $view.FindName("BtnTestSqlConnection")
|
||||||
$btnBackup = $view.FindName("BtnBackupDb")
|
$btnBackup = $view.FindName("BtnBackupDb")
|
||||||
$btnExecQuery = $view.FindName("BtnExecuteQuery")
|
$btnExecQuery = $view.FindName("BtnExecuteQuery")
|
||||||
$txtSqlScript = $view.FindName("TxtSqlScript")
|
|
||||||
$txtSqlOutput = $view.FindName("TxtSqlOutput")
|
|
||||||
$txtSqlStatusMsg = $view.FindName("TxtSqlStatusMsg")
|
|
||||||
$txtSqlTotalCount = $view.FindName("TxtSqlTotalCount")
|
|
||||||
|
|
||||||
$reloadSql = {
|
if ($btnSqlRefresh) { $btnSqlRefresh.add_Click({ & $script:reloadSql }) }
|
||||||
$dbs = Get-SqlDatabases -Config $global:AppConfig
|
|
||||||
if ($dbGrid) { $dbGrid.ItemsSource = $dbs }
|
|
||||||
if ($txtSqlTotalCount) { $txtSqlTotalCount.Text = "총 $($dbs.Count)개 데이터베이스" }
|
|
||||||
if ($txtSqlStatusMsg) {
|
|
||||||
$isLive = ($dbs.Count -gt 0 -and $dbs[0].IsLive)
|
|
||||||
$modeText = if ($isLive) { "실제 SQL Server 연결 ($($global:AppConfig.MsSql.Server))" } else { "데모/시뮬레이션 모드 (System.Data.SqlClient 연동 완비)" }
|
|
||||||
$txtSqlStatusMsg.Text = "상태: $modeText"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($btnSqlRefresh) { $btnSqlRefresh.add_Click($reloadSql) }
|
|
||||||
|
|
||||||
if ($btnTestConn) {
|
if ($btnTestConn) {
|
||||||
$btnTestConn.add_Click({
|
$btnTestConn.add_Click({
|
||||||
@@ -485,25 +594,29 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if ($btnBackup) {
|
if ($btnBackup) {
|
||||||
$btnBackup.add_Click({
|
$btnBackup.add_Click({
|
||||||
$selected = $dbGrid.SelectedItem
|
$v = $ViewCache["Sql"]
|
||||||
|
$g = $v.FindName("SqlDbGrid")
|
||||||
|
$selected = if ($g) { $g.SelectedItem } else { $null }
|
||||||
$dbName = if ($selected) { $selected.DatabaseName } else { "ERP_PRODUCTION" }
|
$dbName = if ($selected) { $selected.DatabaseName } else { "ERP_PRODUCTION" }
|
||||||
$res = Invoke-SqlBackupAction -DatabaseName $dbName -Config $global:AppConfig
|
$res = Invoke-SqlBackupAction -DatabaseName $dbName -Config $global:AppConfig
|
||||||
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Error }
|
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Error }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "SQL 백업 결과", [System.Windows.MessageBoxButton]::OK, $img)
|
[System.Windows.MessageBox]::Show($res.Message, "SQL 백업 결과", [System.Windows.MessageBoxButton]::OK, $img)
|
||||||
&$reloadSql
|
& $script:reloadSql
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($btnExecQuery) {
|
if ($btnExecQuery) {
|
||||||
$btnExecQuery.add_Click({
|
$btnExecQuery.add_Click({
|
||||||
$query = if ($txtSqlScript) { $txtSqlScript.Text } else { "SELECT 1" }
|
$v = $ViewCache["Sql"]
|
||||||
|
$ts = $v.FindName("TxtSqlScript")
|
||||||
|
$to = $v.FindName("TxtSqlOutput")
|
||||||
|
$query = if ($ts) { $ts.Text } else { "SELECT 1" }
|
||||||
$res = Invoke-SqlQuerySnippet -Query $query -Config $global:AppConfig
|
$res = Invoke-SqlQuerySnippet -Query $query -Config $global:AppConfig
|
||||||
if ($txtSqlOutput) { $txtSqlOutput.Text = $res.Output }
|
if ($to) { $to.Text = $res.Output }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
&$reloadSql
|
& $script:reloadSql
|
||||||
$ViewCache["Sql"] = $view
|
|
||||||
}
|
}
|
||||||
$mainContentHost.Content = $ViewCache["Sql"]
|
$mainContentHost.Content = $ViewCache["Sql"]
|
||||||
}
|
}
|
||||||
@@ -514,70 +627,28 @@ function Navigate-ToPage {
|
|||||||
|
|
||||||
if (-not $ViewCache.ContainsKey("Settings")) {
|
if (-not $ViewCache.ContainsKey("Settings")) {
|
||||||
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\SettingsView.xaml")
|
$view = Load-XamlElement -Path (Join-Path $ScriptDir "Views\SettingsView.xaml")
|
||||||
|
$ViewCache["Settings"] = $view
|
||||||
# Controls
|
|
||||||
$chkGlobalLive = $view.FindName("ChkGlobalLiveMode")
|
|
||||||
$chkAdLive = $view.FindName("ChkAdLive")
|
|
||||||
$txtAdDc = $view.FindName("TxtAdDc")
|
|
||||||
$txtAdBaseOu = $view.FindName("TxtAdBaseOu")
|
|
||||||
$chkAdLdaps = $view.FindName("ChkAdLdaps")
|
|
||||||
$txtAdUser = $view.FindName("TxtAdUser")
|
|
||||||
$txtAdPassword = $view.FindName("TxtAdPassword")
|
|
||||||
$btnTestAd = $view.FindName("BtnTestAd")
|
$btnTestAd = $view.FindName("BtnTestAd")
|
||||||
|
|
||||||
$chkNetAppLive = $view.FindName("ChkNetAppLive")
|
|
||||||
$txtNetAppEndpoint = $view.FindName("TxtNetAppEndpoint")
|
|
||||||
$txtNetAppDefaultSvm = $view.FindName("TxtNetAppDefaultSvm")
|
|
||||||
$chkNetAppIgnoreSsl = $view.FindName("ChkNetAppIgnoreSsl")
|
|
||||||
$txtNetAppUser = $view.FindName("TxtNetAppUser")
|
|
||||||
$txtNetAppPassword = $view.FindName("TxtNetAppPassword")
|
|
||||||
$btnTestNetApp = $view.FindName("BtnTestNetApp")
|
$btnTestNetApp = $view.FindName("BtnTestNetApp")
|
||||||
|
|
||||||
$chkSqlLive = $view.FindName("ChkSqlLive")
|
|
||||||
$txtSqlServer = $view.FindName("TxtSqlServer")
|
|
||||||
$cmbSqlAuth = $view.FindName("CmbSqlAuthType")
|
|
||||||
$txtSqlBackupDir = $view.FindName("TxtSqlBackupDir")
|
|
||||||
$txtSqlUser = $view.FindName("TxtSqlUser")
|
|
||||||
$txtSqlPassword = $view.FindName("TxtSqlPassword")
|
|
||||||
$btnTestSql = $view.FindName("BtnTestSql")
|
$btnTestSql = $view.FindName("BtnTestSql")
|
||||||
|
|
||||||
$btnTestAll = $view.FindName("BtnTestAllConnections")
|
$btnTestAll = $view.FindName("BtnTestAllConnections")
|
||||||
$btnSave = $view.FindName("BtnSaveSettings")
|
$btnSave = $view.FindName("BtnSaveSettings")
|
||||||
$btnReload = $view.FindName("BtnReloadConfig")
|
$btnReload = $view.FindName("BtnReloadConfig")
|
||||||
|
|
||||||
# Populate from Config
|
& $script:loadSettingsToUI
|
||||||
$loadSettingsToUI = {
|
|
||||||
$c = $global:AppConfig
|
|
||||||
if ($chkGlobalLive) { $chkGlobalLive.IsChecked = [bool]$c.Application.LiveMode }
|
|
||||||
|
|
||||||
if ($chkAdLive) { $chkAdLive.IsChecked = [bool]$c.ActiveDirectory.UseLive }
|
|
||||||
if ($txtAdDc) { $txtAdDc.Text = $c.ActiveDirectory.DomainController }
|
|
||||||
if ($txtAdBaseOu) { $txtAdBaseOu.Text = $c.ActiveDirectory.BaseOU }
|
|
||||||
if ($chkAdLdaps) { $chkAdLdaps.IsChecked = [bool]$c.ActiveDirectory.UseLdaps }
|
|
||||||
if ($txtAdUser) { $txtAdUser.Text = $c.ActiveDirectory.Username }
|
|
||||||
if ($txtAdPassword) { $txtAdPassword.Password = $c.ActiveDirectory.Password }
|
|
||||||
|
|
||||||
if ($chkNetAppLive) { $chkNetAppLive.IsChecked = [bool]$c.NetApp.UseLive }
|
|
||||||
if ($txtNetAppEndpoint) { $txtNetAppEndpoint.Text = $c.NetApp.ClusterEndpoint }
|
|
||||||
if ($txtNetAppDefaultSvm) { $txtNetAppDefaultSvm.Text = $c.NetApp.DefaultSvm }
|
|
||||||
if ($chkNetAppIgnoreSsl) { $chkNetAppIgnoreSsl.IsChecked = [bool]$c.NetApp.IgnoreSslErrors }
|
|
||||||
if ($txtNetAppUser) { $txtNetAppUser.Text = $c.NetApp.Username }
|
|
||||||
if ($txtNetAppPassword) { $txtNetAppPassword.Password = $c.NetApp.Password }
|
|
||||||
|
|
||||||
if ($chkSqlLive) { $chkSqlLive.IsChecked = [bool]$c.MsSql.UseLive }
|
|
||||||
if ($txtSqlServer) { $txtSqlServer.Text = $c.MsSql.Server }
|
|
||||||
if ($cmbSqlAuth) { $cmbSqlAuth.SelectedIndex = if ($c.MsSql.AuthType -eq "Sql") { 1 } else { 0 } }
|
|
||||||
if ($txtSqlBackupDir) { $txtSqlBackupDir.Text = $c.MsSql.BackupDirectory }
|
|
||||||
if ($txtSqlUser) { $txtSqlUser.Text = $c.MsSql.Username }
|
|
||||||
if ($txtSqlPassword) { $txtSqlPassword.Password = $c.MsSql.Password }
|
|
||||||
}
|
|
||||||
|
|
||||||
&$loadSettingsToUI
|
|
||||||
|
|
||||||
# Test AD
|
# Test AD
|
||||||
if ($btnTestAd) {
|
if ($btnTestAd) {
|
||||||
$btnTestAd.add_Click({
|
$btnTestAd.add_Click({
|
||||||
$res = Test-ADConnection -DomainController $txtAdDc.Text -BaseOU $txtAdBaseOu.Text -Username $txtAdUser.Text -Password $txtAdPassword.Password -UseLdaps $chkAdLdaps.IsChecked
|
$v = $ViewCache["Settings"]
|
||||||
|
$dc = $v.FindName("TxtAdDc").Text
|
||||||
|
$ou = $v.FindName("TxtAdBaseOu").Text
|
||||||
|
$user = $v.FindName("TxtAdUser").Text
|
||||||
|
$pass = $v.FindName("TxtAdPassword").Password
|
||||||
|
$ldaps = $v.FindName("ChkAdLdaps").IsChecked
|
||||||
|
|
||||||
|
$res = Test-ADConnection -DomainController $dc -BaseOU $ou -Username $user -Password $pass -UseLdaps $ldaps
|
||||||
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "AD 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
[System.Windows.MessageBox]::Show($res.Message, "AD 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
||||||
})
|
})
|
||||||
@@ -586,7 +657,13 @@ function Navigate-ToPage {
|
|||||||
# Test NetApp
|
# Test NetApp
|
||||||
if ($btnTestNetApp) {
|
if ($btnTestNetApp) {
|
||||||
$btnTestNetApp.add_Click({
|
$btnTestNetApp.add_Click({
|
||||||
$res = Test-NetAppConnection -ClusterEndpoint $txtNetAppEndpoint.Text -Username $txtNetAppUser.Text -Password $txtNetAppPassword.Password -IgnoreSsl $chkNetAppIgnoreSsl.IsChecked
|
$v = $ViewCache["Settings"]
|
||||||
|
$ep = $v.FindName("TxtNetAppEndpoint").Text
|
||||||
|
$user = $v.FindName("TxtNetAppUser").Text
|
||||||
|
$pass = $v.FindName("TxtNetAppPassword").Password
|
||||||
|
$ignoreSsl = $v.FindName("ChkNetAppIgnoreSsl").IsChecked
|
||||||
|
|
||||||
|
$res = Test-NetAppConnection -ClusterEndpoint $ep -Username $user -Password $pass -IgnoreSsl $ignoreSsl
|
||||||
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "NetApp 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
[System.Windows.MessageBox]::Show($res.Message, "NetApp 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
||||||
})
|
})
|
||||||
@@ -595,8 +672,14 @@ function Navigate-ToPage {
|
|||||||
# Test SQL
|
# Test SQL
|
||||||
if ($btnTestSql) {
|
if ($btnTestSql) {
|
||||||
$btnTestSql.add_Click({
|
$btnTestSql.add_Click({
|
||||||
$authType = if ($cmbSqlAuth.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
$v = $ViewCache["Settings"]
|
||||||
$res = Test-SqlConnection -Server $txtSqlServer.Text -AuthType $authType -Username $txtSqlUser.Text -Password $txtSqlPassword.Password
|
$srv = $v.FindName("TxtSqlServer").Text
|
||||||
|
$cmb = $v.FindName("CmbSqlAuthType")
|
||||||
|
$authType = if ($cmb.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
||||||
|
$user = $v.FindName("TxtSqlUser").Text
|
||||||
|
$pass = $v.FindName("TxtSqlPassword").Password
|
||||||
|
|
||||||
|
$res = Test-SqlConnection -Server $srv -AuthType $authType -Username $user -Password $pass
|
||||||
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
$img = if ($res.Success) { [System.Windows.MessageBoxImage]::Information } else { [System.Windows.MessageBoxImage]::Warning }
|
||||||
[System.Windows.MessageBox]::Show($res.Message, "MS SQL 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
[System.Windows.MessageBox]::Show($res.Message, "MS SQL 연결 테스트", [System.Windows.MessageBoxButton]::OK, $img)
|
||||||
})
|
})
|
||||||
@@ -605,23 +688,40 @@ function Navigate-ToPage {
|
|||||||
# Test All
|
# Test All
|
||||||
if ($btnTestAll) {
|
if ($btnTestAll) {
|
||||||
$btnTestAll.add_Click({
|
$btnTestAll.add_Click({
|
||||||
$adRes = Test-ADConnection -DomainController $txtAdDc.Text -BaseOU $txtAdBaseOu.Text -Username $txtAdUser.Text -Password $txtAdPassword.Password -UseLdaps $chkAdLdaps.IsChecked
|
$v = $ViewCache["Settings"]
|
||||||
$netappRes = Test-NetAppConnection -ClusterEndpoint $txtNetAppEndpoint.Text -Username $txtNetAppUser.Text -Password $txtNetAppPassword.Password -IgnoreSsl $chkNetAppIgnoreSsl.IsChecked
|
$dc = $v.FindName("TxtAdDc").Text
|
||||||
$authType = if ($cmbSqlAuth.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
$ou = $v.FindName("TxtAdBaseOu").Text
|
||||||
$sqlRes = Test-SqlConnection -Server $txtSqlServer.Text -AuthType $authType -Username $txtSqlUser.Text -Password $txtSqlPassword.Password
|
$user = $v.FindName("TxtAdUser").Text
|
||||||
|
$pass = $v.FindName("TxtAdPassword").Password
|
||||||
|
$ldaps = $v.FindName("ChkAdLdaps").IsChecked
|
||||||
|
|
||||||
|
$ep = $v.FindName("TxtNetAppEndpoint").Text
|
||||||
|
$nUser = $v.FindName("TxtNetAppUser").Text
|
||||||
|
$nPass = $v.FindName("TxtNetAppPassword").Password
|
||||||
|
$ignoreSsl = $v.FindName("ChkNetAppIgnoreSsl").IsChecked
|
||||||
|
|
||||||
|
$srv = $v.FindName("TxtSqlServer").Text
|
||||||
|
$cmb = $v.FindName("CmbSqlAuthType")
|
||||||
|
$authType = if ($cmb.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
||||||
|
$sUser = $v.FindName("TxtSqlUser").Text
|
||||||
|
$sPass = $v.FindName("TxtSqlPassword").Password
|
||||||
|
|
||||||
|
$adRes = Test-ADConnection -DomainController $dc -BaseOU $ou -Username $user -Password $pass -UseLdaps $ldaps
|
||||||
|
$netappRes = Test-NetAppConnection -ClusterEndpoint $ep -Username $nUser -Password $nPass -IgnoreSsl $ignoreSsl
|
||||||
|
$sqlRes = Test-SqlConnection -Server $srv -AuthType $authType -Username $sUser -Password $sPass
|
||||||
|
|
||||||
$report = @"
|
$report = @"
|
||||||
=== 전체 인프라 일괄 진단 결과 ===
|
=== 전체 인프라 일괄 진단 결과 ===
|
||||||
|
|
||||||
[1] Active Directory (DC: $($txtAdDc.Text))
|
[1] Active Directory (DC: $dc)
|
||||||
- 상태: $(if ($adRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
- 상태: $(if ($adRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
||||||
- 세부: $($adRes.Message)
|
- 세부: $($adRes.Message)
|
||||||
|
|
||||||
[2] NetApp ONTAP REST API ($($txtNetAppEndpoint.Text))
|
[2] NetApp ONTAP REST API ($ep)
|
||||||
- 상태: $(if ($netappRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
- 상태: $(if ($netappRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
||||||
- 세부: $($netappRes.Message)
|
- 세부: $($netappRes.Message)
|
||||||
|
|
||||||
[3] MS SQL Server ($($txtSqlServer.Text))
|
[3] MS SQL Server ($srv)
|
||||||
- 상태: $(if ($sqlRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
- 상태: $(if ($sqlRes.Success) { '√ 정상 연결' } else { 'X 연결 실패' })
|
||||||
- 세부: $($sqlRes.Message)
|
- 세부: $($sqlRes.Message)
|
||||||
"@
|
"@
|
||||||
@@ -632,7 +732,15 @@ function Navigate-ToPage {
|
|||||||
# Save Settings
|
# Save Settings
|
||||||
if ($btnSave) {
|
if ($btnSave) {
|
||||||
$btnSave.add_Click({
|
$btnSave.add_Click({
|
||||||
$authType = if ($cmbSqlAuth.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
$v = $ViewCache["Settings"]
|
||||||
|
$cmb = $v.FindName("CmbSqlAuthType")
|
||||||
|
$authType = if ($cmb.SelectedIndex -eq 1) { "Sql" } else { "Integrated" }
|
||||||
|
|
||||||
|
$chkGlobalLive = $v.FindName("ChkGlobalLiveMode")
|
||||||
|
$chkAdLive = $v.FindName("ChkAdLive")
|
||||||
|
$chkNetAppLive = $v.FindName("ChkNetAppLive")
|
||||||
|
$chkSqlLive = $v.FindName("ChkSqlLive")
|
||||||
|
|
||||||
$newConfig = @{
|
$newConfig = @{
|
||||||
Application = @{
|
Application = @{
|
||||||
LiveMode = [bool]$chkGlobalLive.IsChecked
|
LiveMode = [bool]$chkGlobalLive.IsChecked
|
||||||
@@ -641,31 +749,31 @@ function Navigate-ToPage {
|
|||||||
}
|
}
|
||||||
ActiveDirectory = @{
|
ActiveDirectory = @{
|
||||||
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkAdLive.IsChecked)
|
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkAdLive.IsChecked)
|
||||||
DomainController = $txtAdDc.Text
|
DomainController = $v.FindName("TxtAdDc").Text
|
||||||
Domain = "corp.local"
|
Domain = "corp.local"
|
||||||
BaseOU = $txtAdBaseOu.Text
|
BaseOU = $v.FindName("TxtAdBaseOu").Text
|
||||||
UseLdaps = [bool]$chkAdLdaps.IsChecked
|
UseLdaps = [bool]$v.FindName("ChkAdLdaps").IsChecked
|
||||||
Username = $txtAdUser.Text
|
Username = $v.FindName("TxtAdUser").Text
|
||||||
Password = $txtAdPassword.Password
|
Password = $v.FindName("TxtAdPassword").Password
|
||||||
}
|
}
|
||||||
NetApp = @{
|
NetApp = @{
|
||||||
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkNetAppLive.IsChecked)
|
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkNetAppLive.IsChecked)
|
||||||
ClusterEndpoint = $txtNetAppEndpoint.Text
|
ClusterEndpoint = $v.FindName("TxtNetAppEndpoint").Text
|
||||||
Port = 443
|
Port = 443
|
||||||
DefaultSvm = $txtNetAppDefaultSvm.Text
|
DefaultSvm = $v.FindName("TxtNetAppDefaultSvm").Text
|
||||||
Username = $txtNetAppUser.Text
|
Username = $v.FindName("TxtNetAppUser").Text
|
||||||
Password = $txtNetAppPassword.Password
|
Password = $v.FindName("TxtNetAppPassword").Password
|
||||||
IgnoreSslErrors = [bool]$chkNetAppIgnoreSsl.IsChecked
|
IgnoreSslErrors = [bool]$v.FindName("ChkNetAppIgnoreSsl").IsChecked
|
||||||
}
|
}
|
||||||
MsSql = @{
|
MsSql = @{
|
||||||
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkSqlLive.IsChecked)
|
UseLive = [bool]($chkGlobalLive.IsChecked -or $chkSqlLive.IsChecked)
|
||||||
Server = $txtSqlServer.Text
|
Server = $v.FindName("TxtSqlServer").Text
|
||||||
AuthType = $authType
|
AuthType = $authType
|
||||||
Username = $txtSqlUser.Text
|
Username = $v.FindName("TxtSqlUser").Text
|
||||||
Password = $txtSqlPassword.Password
|
Password = $v.FindName("TxtSqlPassword").Password
|
||||||
DefaultDatabase = "master"
|
DefaultDatabase = "master"
|
||||||
ConnectionTimeout = 10
|
ConnectionTimeout = 10
|
||||||
BackupDirectory = $txtSqlBackupDir.Text
|
BackupDirectory = $v.FindName("TxtSqlBackupDir").Text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,9 +781,9 @@ function Navigate-ToPage {
|
|||||||
$global:AppConfig = Get-AppConfig
|
$global:AppConfig = Get-AppConfig
|
||||||
Update-ModeBadgeUI
|
Update-ModeBadgeUI
|
||||||
|
|
||||||
# Invalidate view caches so next click loads fresh live data
|
|
||||||
$ViewCache.Remove("AD")
|
$ViewCache.Remove("AD")
|
||||||
$ViewCache.Remove("NetApp")
|
$ViewCache.Remove("NetApp")
|
||||||
|
$ViewCache.Remove("ShareAccess")
|
||||||
$ViewCache.Remove("Sql")
|
$ViewCache.Remove("Sql")
|
||||||
|
|
||||||
[System.Windows.MessageBox]::Show("환경설정이 성공적으로 저장되었습니다.`n각 관리 화면에서 변경된 접속 정보가 즉시 적용됩니다.", "저장 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show("환경설정이 성공적으로 저장되었습니다.`n각 관리 화면에서 변경된 접속 정보가 즉시 적용됩니다.", "저장 완료", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
@@ -685,13 +793,11 @@ function Navigate-ToPage {
|
|||||||
if ($btnReload) {
|
if ($btnReload) {
|
||||||
$btnReload.add_Click({
|
$btnReload.add_Click({
|
||||||
$global:AppConfig = Get-AppConfig
|
$global:AppConfig = Get-AppConfig
|
||||||
&$loadSettingsToUI
|
& $script:loadSettingsToUI
|
||||||
Update-ModeBadgeUI
|
Update-ModeBadgeUI
|
||||||
[System.Windows.MessageBox]::Show("config.json 설정을 다시 불러왔습니다.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
[System.Windows.MessageBox]::Show("config.json 설정을 다시 불러왔습니다.", "알림", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
$ViewCache["Settings"] = $view
|
|
||||||
}
|
}
|
||||||
$mainContentHost.Content = $ViewCache["Settings"]
|
$mainContentHost.Content = $ViewCache["Settings"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user