View/Initialize-MainWindowUIJob.Task.ps1

[Flags()]Enum MSFT_ScheduledTaskDaysOfWeek{
    Sunday = 1
    Monday = 2
    Tuesday = 4
    Wednesday = 8
    Thursday = 16
    Friday = 32
    Saturday = 64
}
[Flags()]Enum MSFT_ScheduledTaskWeeksOfMonth{
    First = 1
    Second = 2
    Third = 4
    Fourth = 8
}
[Flags()]Enum MSFT_ScheduledTaskTrigger{
    Event = 0
    Time = 1
    Daily = 2
    Weekly = 3
    Monthly = 4
    MonthlyDayOfWeek = 5
    Idle = 6
    Registration = 7
    Boot = 8
    Logon = 9
    SessionStateChange = 11
    CustomTrigger01 = 12
}

Function Global:Initialize-MainWindowUIJob{
    Class StatusItem{
        $Status
        $IsCompleted
    }

    $Global:StatusList = @()
    If (!$CurrentConfig.WizardView.DetectiveInstalledComponents -or !$CurrentConfig.WizardView.ShowOptionTab){
    }
    Else{
        $Global:ComponentsListViewUIStatus = New-Object StatusItem
        $Global:ComponentsListViewUIStatus.Status = "インストール済みコンポーネント"
        $Global:StatusList += $ComponentsListViewUIStatus
        $MainWindow.Dispatcher.Invoke({$MainWindow.FindName("StatusList").DataContext = $StatusList})
        Initialize-ComponentsListViewUI
    }
    
    $Global:TaskListListViewUIStatus = New-Object StatusItem
    $Global:TaskListListViewUIStatus.Status = "タスク"
    $Global:StatusList += $TaskListListViewUIStatus
    $MainWindow.Dispatcher.Invoke({$MainWindow.FindName("StatusList").DataContext = $StatusList})
    Initialize-ScheduleTaskUI

    $MainWindow.Dispatcher.Invoke({
        $MainWindow.FindName("IndicatorRoot").Visibility = [System.Windows.Visibility]::Collapsed
    })
}

Function Global:Initialize-ComponentsListViewUI{
    
    Get-InstalledComponents

    $MainWindow.Dispatcher.Invoke({
        $MainWindow.FindName("ComponentsListView").DataContext = $ComponentsList
        If (@($ComponentsList).Count -gt 0){
            $MainWindow.FindName("ComponentsListContainer").Visibility = [System.Windows.Visibility]::Visible
        }
        If ($CurrentConfig.MaintenanceSql.SqlCmdExeMode -eq "exe"){
            $MainWindow.FindName("SqlCmdContainer").Visibility = [System.Windows.Visibility]::Visible
        }
    })
}

Function Global:Initialize-WsusProductUI{
    (Get-WsusProduct -TitleIncludes "Microsoft" | Where-Object {$_.Product.Id -eq "56309036-4c77-4dd9-951a-99ee9c246a94"}).Product.GetSubcategories() | Where-Object Type -eq ProductFamily
    (Get-WsusProduct -TitleIncludes "Windows" | Where-Object {$_.Product.Id -eq "6964aab4-c5b5-43bd-a17d-ffb4346a8e1d"}).Product.GetSubcategories()
    (Get-WsusProduct -TitleIncludes "Office" | Where-Object {$_.Product.Id -eq "477b856e-65c4-4473-b621-a8b230bb70d9"}).Product.GetSubcategories()
}

Function Global:Initialize-ScheduleTaskUI{
    Try{
        $Item = New-Object SchedukeTaskTriggerItem

        #Write-Verbose "タスク $($CurrentConfig.ScheduledTask.Name) の調査中..."

        $ScheduleService = New-Object -ComObject Schedule.Service
        $ScheduleService.Connect()
        $ScheduleTask = $ScheduleService.GetFolder("\").GetTasks(0) | Where-Object Name -Like "$($CurrentConfig.ScheduledTask.Name)*"
        If ($ScheduleTask -ne $null){
            Write-Verbose "タスク $($CurrentConfig.ScheduledTask.Name) が見つかりました"
            If ($ScheduleTask.Definition.Triggers.Count -eq 0){
                Write-Verbose "-> $($CurrentConfig.ScheduledTask.Name) にトリガーが見つかりませんでした"
            }
            Else{
                If ($ScheduleTask.Definition.Triggers.Count -ne 1){
                    Write-Verbose "-> 複数のトリガーが見つかりました。1個目のトリガーのみが反映されます。"
                }
                #$ScheduleTask.Definition.Triggers | ForEach-Object {
                Try{
                    $ScheduledTaskTrigger = $ScheduleTask.Definition.Triggers[1]
                    Write-Verbose "-> Trigger type: $(([MSFT_ScheduledTaskTrigger]$ScheduledTaskTrigger.Type).ToString())"

                    Switch([MSFT_ScheduledTaskTrigger]$ScheduledTaskTrigger.Type){
                        ([MSFT_ScheduledTaskTrigger]::Daily) {
                            Write-Verbose "-> [Daily]"

                            $Item.Sunday = $True
                            $Item.Monday = $True
                            $Item.Tuesday = $True
                            $Item.Wednesday = $True
                            $Item.Thursday = $True
                            $Item.Friday = $True
                            $Item.Saturday = $True

                            $Item.StartBoundary = $ScheduledTaskTrigger.StartBoundary

                            $Item.LoadedDaysOfWeek = $True
                        }
                        ([MSFT_ScheduledTaskTrigger]::Weekly) {
                            $ScheduleTaskDaysOfWeek = ([MSFT_ScheduledTaskDaysOfWeek]$ScheduledTaskTrigger.DaysOfWeek)

                            $Item.Sunday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Sunday)
                            $Item.Monday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Monday)
                            $Item.Tuesday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Tuesday)
                            $Item.Wednesday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Wednesday)
                            $Item.Thursday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Thursday)
                            $Item.Friday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Friday)
                            $Item.Saturday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Saturday)

                            $Item.StartBoundary = $ScheduledTaskTrigger.StartBoundary

                            $Item.LoadedDaysOfWeek = $True
                        }
                        ([MSFT_ScheduledTaskTrigger]::MonthlyDayOfWeek) {
                            $ScheduleTaskWeeksOfMonth = ([MSFT_ScheduledTaskWeeksOfMonth]$ScheduledTaskTrigger.WeeksOfMonth)

                            $Item.First = $ScheduleTaskWeeksOfMonth.HasFlag([MSFT_ScheduledTaskWeeksOfMonth]::First)
                            $Item.Second = $ScheduleTaskWeeksOfMonth.HasFlag([MSFT_ScheduledTaskWeeksOfMonth]::Second)
                            $Item.Third = $ScheduleTaskWeeksOfMonth.HasFlag([MSFT_ScheduledTaskWeeksOfMonth]::Third)
                            $Item.Fourth = $ScheduleTaskWeeksOfMonth.HasFlag([MSFT_ScheduledTaskWeeksOfMonth]::Fourth)
                            $Item.Last = $ScheduledTaskTrigger.RunOnLastWeekOfMonth
                            

                            $ScheduleTaskDaysOfWeek = ([MSFT_ScheduledTaskDaysOfWeek]$ScheduledTaskTrigger.DaysOfWeek)

                            $Item.Sunday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Sunday)
                            $Item.Monday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Monday)
                            $Item.Tuesday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Tuesday)
                            $Item.Wednesday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Wednesday)
                            $Item.Thursday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Thursday)
                            $Item.Friday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Friday)
                            $Item.Saturday = $ScheduleTaskDaysOfWeek.HasFlag([MSFT_ScheduledTaskDaysOfWeek]::Saturday)

                            $Item.StartBoundary = $ScheduledTaskTrigger.StartBoundary

                            $Item.LoadedDaysOfWeek = $True
                            $Item.LoadedWeeksOfMonth = $True
                        }
                        Default{
                            Write-Warning "-> タイプ $(([MSFT_ScheduledTaskTrigger]$ScheduledTaskTrigger.Type).ToString()) の読み込みはサポートしません"
                        }
                    }
                }
                Catch{
                    Write-Error "タスクの読み取りに失敗しました: $($_.Exception.Message)"
                }
                #}


            }
        }
        Else{
            Write-Verbose "タスク $($CurrentConfig.ScheduledTask.Name) は見つかりませんでした"
        }

        Try{
            If ($ScheduledTaskTrigger.DaysOfWeek -ne $Null){
                Write-Verbose "-> $(([MSFT_ScheduledTaskDaysOfWeek]$ScheduledTaskTrigger.DaysOfWeek).ToString())"
            }
            If ($ScheduledTaskTrigger.WeeksOfMonth -ne $Null){
                Write-Verbose "-> $(([MSFT_ScheduledTaskWeeksOfMonth]$ScheduledTaskTrigger.WeeksOfMonth).ToString())"
            }
            Write-Verbose "-> StartBoundary: $($Item.StartBoundary), LoadedDaysOfWeek: $($Item.LoadedDaysOfWeek), LoadedWeeksOfMonth: $($Item.LoadedWeeksOfMonth)"
        }
        Catch{
            Write-Verbose "タスク $($CurrentConfig.ScheduledTask.Name) の詳細出力に失敗しました"
        }

        $MainWindow.Dispatcher.Invoke({
            $MainWindow.FindName("ScheduleTab").DataContext = $Item
            $MainWindow.FindName("EditiingScheduleTriggersCheckBox").DataContext = $Item
            $MainWindow.FindName("EditiingScheduleTriggersCheckBox").IsEnabled = $True
            #$MainWindow.FindName("MonthlyScheduleCheckBox").DataContext = $Item

            $MainWindow.FindName("WeeklyScheduleSundayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleMondayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleTuesdayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleWednesdayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleThursdayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleFridayCheckBox").DataContext = $Item
            $MainWindow.FindName("WeeklyScheduleSaturdayCheckBox").DataContext = $Item
            
            $MainWindow.FindName("MonthlyScheduleFirstCheckBox").DataContext = $Item
            $MainWindow.FindName("MonthlyScheduleSecondCheckBox").DataContext = $Item
            $MainWindow.FindName("MonthlyScheduleThirdCheckBox").DataContext = $Item
            $MainWindow.FindName("MonthlyScheduleFourthCheckBox").DataContext = $Item
            $MainWindow.FindName("MonthlyScheduleLastCheckBox").DataContext = $Item

            $MainWindow.FindName("WeeklyScheduleDateTimePicker").Value = $Item.StartBoundary
            
            
        })
        #Write-Verbose "タスク $($CurrentConfig.ScheduledTask.Name) の調査が終わりました"
    }
    Catch{
        Write-Error "タスクの読み取りに失敗しました: $($_.Exception.Message)"
    }
}

Function Global:Get-InstalledComponents{
    Write-Verbose "`n`nインストール済みコンポーネントの調査中..."
    $UninstallRootKeyPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
    $UninstallWOW6432NodeRootKeyPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
    $MsiexecPath = "$env:SystemRoot\System32\msiexec.exe"
    $OptionComponents = Get-Content (Join-Path $PSScriptRoot "..\Assets\OptionComponents.json") -Encoding UTF8 | ConvertFrom-Json

    $Win32Products = Get-WmiObject Win32_Product
    #$Global:ComponentsListViewUIStatus.Status = "確認しました"

    Write-Verbose "インストール済みコンポーネントの調査結果:`n"

    $Global:ComponentsList = @()

    # SqlCmdExeMode モードの指定が PowerShell となっている場合はインストール対象から外す
    If ($CurrentConfig.MaintenanceSql.SqlCmdExeMode -eq "psmodule"){
        $OptionComponents.Components = $OptionComponents.Components | Where-Object Type -ne "DatabaseMaintenance"
    }
    
    $OptionComponents.Components | ForEach-Object {
        $Item = New-Object OptionComponentsItem
        $Item.DisplayName = $_.DisplayName
        $Item.Reason = $_.Reason
        $Item.FileName = $_.FileName
        $Item.AcceptEula = $_.AcceptEula
        $Item.DownloadUrl = $_.DownloadUrl
        $Item.DetailsUrl = $_.DetailsUrl
        $Item.SilentInstall = $_.SilentInstall
        $Item.WindowsFeatureName = $_.WindowsFeatureName
        $Item.Type = $_.Type
        $Item.Installed = $False
        $Item.IsSelected = $False
        $Item.IsEnabled = $True
        $Item.Status = "未インストール"

        If ($Item.Type -eq "WindowsFeature"){
            Try{
                $Item.Installed = (Get-WindowsFeature $Item.WindowsFeatureName).Installed
                If ($Item.Installed){
                    $Item.Installed = $True
                    $Item.IsSelected = $True
                    $Item.IsEnabled = $False
                    $Item.Status = "インストール済み"
                    Write-Verbose "インストール済み: $($Item.DisplayName)"
                }
                Else{
                    Write-Verbose "未インストール: $($Item.DisplayName)"
                }
            }
            Catch{
                $Item.Installed = $False
                $Item.IsSelected = $False
                $Item.IsEnabled = $False
                $Item.Status = "インストール不可: $($_.Exception.Message)"
                Write-Verbose "インストール不可: $($Item.DisplayName) ($($_.Exception.Message))"
            }
        }

        :GetOptionComponents
        ForEach($CheckCurrentVersionItem in $_.CheckCurrentVersion){
            $IdentifyingNumber = $CheckCurrentVersionItem.IdentifyingNumber
            $DisplayVersionText = $CheckCurrentVersionItem.DisplayVersion
            $DisplayName = $CheckCurrentVersionItem.DisplayName
            $KeyIsWOW6432Node = $CheckCurrentVersionItem.KeyIsWOW6432Node

            $UninstallKeyPath = ($UninstallRootKeyPath + $IdentifyingNumber)
            If ($KeyIsWOW6432Node){
                $UninstallKeyPath = ($UninstallWOW6432NodeRootKeyPath + $IdentifyingNumber)
            }
            If (Test-Path -Path $UninstallKeyPath){
                $Item.Installed = $True
                $Item.IsSelected = $True
                $Item.IsEnabled = $False
                $Item.Status = "インストール済み: $DisplayName ($DisplayVersionText)"
                Write-Verbose "`nインストール済み: $DisplayName ($DisplayVersionText)"
                Break GetOptionComponents
            }
            Else{
                #IdentifyingNumber is not found
                Write-Verbose "`n未インストール: $DisplayName"
                $Win32ProductsName = $CheckCurrentVersionItem.Win32ProductsName
                If ($Win32ProductsName -eq $null){
                    $Win32ProductsName = $CheckCurrentVersionItem.DisplayName
                }
                $NearProducts = $Win32Products | Where-Object Name -Like "$($Win32ProductsName)*"
                If ($NearProducts -ne $null){
                    $InstalledNameText = $NearProducts.Name
                    $InstalledVersionText = $NearProducts.Version
                    $Item.Installed = $True
                    $Item.IsSelected = $True
                    $Item.IsEnabled = $False
                    $Item.Status = "インストール済み: $InstalledNameText ($InstalledVersionText)"
                    Write-Verbose "-> 類似製品を検出: $InstalledNameText ($InstalledVersionText)"
                    Break GetOptionComponents
                }
                Else{
                    Write-Verbose "-> 類似製品は検出されませんでした: $($Win32ProductsName)"
                }
            }
        }

        $Global:ComponentsList += $Item
    }
    Write-Verbose "`n`nインストール済みコンポーネントの調査が終わりました"
}