Scripts/Config.ps1

$LegacyNameFiltersDirectory = "DeclineFilters\LegacyName"
$TitleFiltersDirectory = "DeclineFilters\Title.en"

Enum WsusFilteredUpdatesMode{
    Unknown
    Full
    H1
    H2
    H3
    H4
    H5
}

Function Global:Get-ProgramDataDirectory{
    $DirectoryPath = "$env:ProgramData\Wsustainable\0.1"
    New-Item -Path $DirectoryPath -ItemType Directory -Force | Out-Null
    New-Item -Path (Join-Path $DirectoryPath "Installers") -ItemType Directory -Force | Out-Null
    Return $DirectoryPath
}

Function Global:Get-DeclineRules($Config){
    Function Export-ChoosedFiltersPerWindowsProduct([WindowsVersion]$Target){
        Enum WindowsVersion{
            Windows10
            Windows11
        }
        $ChoosedFilters = @()
        Switch ($Target){
            Windows11{
                $Legacynames = (Import-Csv (Join-Path $PSScriptRoot "..\Assets\Legacynames--Windows 11.csv") -Encoding UTF8)
                $ProductName = "Windows 11"
                $Products = $Config.ChooseProducts."Windows 11"
            }
            Windows10{
                $Legacynames = (Import-Csv (Join-Path $PSScriptRoot "..\Assets\Legacynames--Windows 10.csv") -Encoding UTF8)
                $ProductName = "Windows 10"
                $Products = $Config.ChooseProducts."Windows 10"
            }
        }
        $FilePath = (Join-Path (Get-ProgramDataDirectory) "Choosed Filters--$ProductName.txt")
        Remove-Item -Path $FilePath -Force -ErrorAction Ignore | Out-Null

        $SupportedTypeFilter = @("Feature On Demand","Dynamic Update","Language Pack")

        ForEach($Product in $Products) {
            $TargetVersion = $Product.Version
            If ($Target -eq "Windows10" -and $Config.DeclineOptions.IgnoreWindows10Version1809AndEarlier -and $TargetVersion -le 1809){
                Continue
            }
            
            #If (-not $Config.DeclineOptions.SystemType.x86 -and -not $Config.DeclineOptions.SystemType.x64 -and -not $Config.DeclineOptions.SystemType.arm64){
                #$ChoosedFilters += @("# $($TargetVersion) all")
                #$ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $TargetVersion -eq $TargetVersion -and $_.Architecture -eq "all" -and $_.Type -notin $SupportedTypeFilter}).Filter
            #}
            #Else{
                If (-not $Product.x86 -and -not $Config.DeclineOptions.SystemType.x86){
                    $ChoosedFilters += @("# $TargetVersion x86")
                    $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -eq $TargetVersion -and $_.Architecture -eq "x86" -and $_.Type -notin $SupportedTypeFilter}).Filter
                }
                If (-not $Product.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                    $ChoosedFilters += @("# $TargetVersion x64")
                    $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -eq $TargetVersion -and $_.Architecture -eq "x64" -and $_.Type -notin $SupportedTypeFilter}).Filter
                }
                If (-not $Product.arm64 -and -not $Config.DeclineOptions.SystemType.arm64){
                    $ChoosedFilters += @("# $TargetVersion arm64")
                    $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -eq $TargetVersion -and $_.Architecture -eq "arm64" -and $_.Type -notin $SupportedTypeFilter}).Filter
                }
            #}
        }

        If ($Target -eq "Windows10" -and $Config.DeclineOptions.IgnoreWindows10Version1809AndEarlier -and $TargetVersion -le 1809){
            $TargetVersion = 1809
        }
        Else{
            $TargetVersion = 0
        }

        ## Feature On Demand
        If ($Config.DeclineOptions.FeatureOnDemand){
            If (-not $_.x86 -and -not $Config.DeclineOptions.SystemType.x86){
                $ChoosedFilters += @("# Feature On Demand x86")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Feature On Demand" -and $_.Architecture -eq "x86"}).Filter
            }
            If (-not $_.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# Feature On Demand x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Feature On Demand" -and $_.Architecture -eq "x64"}).Filter
            }
            If (-not $_.arm64 -and -not $Config.DeclineOptions.SystemType.arm64){
                $ChoosedFilters += @("# Feature On Demand arm64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Feature On Demand" -and $_.Architecture -eq "arm64"}).Filter
            }
        }
        ## Dynamic Update
        If ($Config.DeclineOptions.DynamicUpdate){
            If (-not $_.x86 -and -not $Config.DeclineOptions.SystemType.x86){
                $ChoosedFilters += @("# Dynamic Update x86")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Dynamic Update" -and $_.Architecture -eq "x86"}).Filter
            }
            If (-not $_.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# Dynamic Update x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Dynamic Update" -and $_.Architecture -eq "x64"}).Filter
            }
            If (-not $_.arm64 -and -not $Config.DeclineOptions.SystemType.arm64){
                $ChoosedFilters += @("# Dynamic Update arm64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Dynamic Update" -and $_.Architecture -eq "arm64"}).Filter
            }
        }
        ## 言語パック
        If ($Config.DeclineOptions.LanguagePack){
            If (-not $_.x86 -and -not $Config.DeclineOptions.SystemType.x86){
                $ChoosedFilters += @("# Language Pack x86")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Language Pack" -and $_.Architecture -eq "x86"}).Filter
            }
            If (-not $_.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# Language Pack x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Language Pack" -and $_.Architecture -eq "x64"}).Filter
            }
            If (-not $_.arm64 -and -not $Config.DeclineOptions.SystemType.arm64){
                $ChoosedFilters += @("# Language Pack arm64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq $ProductName -and $_.Version -le $TargetVersion -and $_.Type -eq "Language Pack" -and $_.Architecture -eq "arm64"}).Filter
            }
        }
        ## Windows Server
        If ($Config.DeclineOptions.WindowsServer){
            If (-not $_.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# Windows Server x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -like "Windows Server*" -and $_.Architecture -eq "x64"}).Filter
            }
        }
        ## Insider
        If ($Config.DeclineOptions.InsiderPreview){
            If (-not $_.x86 -and -not $Config.DeclineOptions.SystemType.x86){
                $ChoosedFilters += @("# Insider Preview x86")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq "Insider Preview" -and $_.Version -le $TargetVersion -and $_.Architecture -eq "x86"}).Filter
            }
            If (-not $_.x64 -and -not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# Insider Preview x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq "Insider Preview" -and $_.Version -le $TargetVersion -and $_.Architecture -eq "x64"}).Filter
            }
            If (-not $_.arm64 -and -not $Config.DeclineOptions.SystemType.arm64){
                $ChoosedFilters += @("# Insider Preview arm64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Product -eq "Insider Preview" -and $_.Version -le $TargetVersion -and $_.Architecture -eq "arm64"}).Filter
            }
        }


        If ($ChoosedFilters.Count -ne 0){
            $ChoosedFilters | Get-Unique | Out-File -FilePath $FilePath -Encoding UTF8 -Append
            Return $FilePath
        }
    }
    Function Export-ChoosedFiltersPerMsEdge([Switch]$DeclineOldVersions = $False){
        $ChoosedFilters = @()
        $Legacynames = (Import-Csv (Join-Path $PSScriptRoot "..\Assets\Legacynames--Microsoft Edge.csv") -Encoding UTF8)
        $FilePath = "Microsoft Edge"

        If ($DeclineOldVersions){
            $FilePath = (Join-Path (Get-ProgramDataDirectory) "Custom Filters--$FilePath.DeclineOldVersions.txt")
        }
        Else{
            $FilePath = (Join-Path (Get-ProgramDataDirectory) "Custom Filters--$FilePath.txt")
        }
        Remove-Item -Path $FilePath -Force -ErrorAction Ignore | Out-Null
        
        $TargetTypes = @()
        If ($DeclineOldVersions){
            If (-not $Config.DeclineOptions."Microsoft Edge".Beta){
                $TargetTypes += @("Beta")
            }
            If (-not $Config.DeclineOptions."Microsoft Edge".Dev){
                $TargetTypes += @("Dev")
            }
            If (-not $Config.DeclineOptions."Microsoft Edge".Stable){
                $TargetTypes += @("Stable")
            }
            If (-not $Config.DeclineOptions."Microsoft Edge".ExtendedStable){
                $TargetTypes += @("ExtendedStable")
            }
            If (-not $Config.DeclineOptions."Microsoft Edge".WebView2Runtime){
                $TargetTypes += @("WebView2Runtime")
            }
        }
        Else{
            If ($Config.DeclineOptions."Microsoft Edge".Beta){
                $TargetTypes += @("Beta")
            }
            If ($Config.DeclineOptions."Microsoft Edge".Dev){
                $TargetTypes += @("Dev")
            }
            If ($Config.DeclineOptions."Microsoft Edge".Stable){
                $TargetTypes += @("Stable")
            }
            If ($Config.DeclineOptions."Microsoft Edge".ExtendedStable){
                $TargetTypes += @("ExtendedStable")
            }
            If ($Config.DeclineOptions."Microsoft Edge".WebView2Runtime){
                $TargetTypes += @("WebView2Runtime")
            }
        }

        If (-not $Config.DeclineOptions.SystemType.x86 -and -not $Config.DeclineOptions.SystemType.x64 -and -not $Config.DeclineOptions.SystemType.arm64){
            $ChoosedFilters += @("# all")
            $ChoosedFilters += ($Legacynames | Where-Object {$_.Type -in $TargetTypes -and $_.Architecture -eq "all"}).Filter
        }
        Else{
            If (-not $Config.DeclineOptions.SystemType.x86){
                $ChoosedFilters += @("# x86")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Type -in $TargetTypes -and $_.Architecture -eq "x86"}).Filter
            }
            If (-not $Config.DeclineOptions.SystemType.x64){
                $ChoosedFilters += @("# x64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Type -in $TargetTypes -and $_.Architecture -eq "x64"}).Filter
            }
            If (-not $Config.DeclineOptions.SystemType.arm64){
                $ChoosedFilters += @("# arm64")
                $ChoosedFilters += ($Legacynames | Where-Object {$_.Type -in $TargetTypes -and $_.Architecture -eq "arm64"}).Filter
            }
        }


        If ($ChoosedFilters.Count -ne 0){
            $ChoosedFilters | Get-Unique | Out-File -FilePath $FilePath -Encoding UTF8 -Append
            Return $FilePath
        }
    }

    # Decline rules
    $DeclineRules = @()

    $DeclineChoosedFilters = Get-Content (Join-Path $PSScriptRoot "..\DeclineRules\Windows--Decline Windows custom filters.json") -Encoding UTF8 | ConvertFrom-Json
    $LegacyNameFilterPath = @()
    ## Windows 11
    $Windows11FilterPath = Export-ChoosedFiltersPerWindowsProduct -Target Windows11
    If ($Windows11FilterPath -ne $Null){
        $LegacyNameFilterPath += $Windows11FilterPath
    }
    ## Windows 10
    $Windows10FilterPath = Export-ChoosedFiltersPerWindowsProduct -Target Windows10
    If ($Windows10FilterPath -ne $Null){
        $LegacyNameFilterPath += $Windows10FilterPath
    }
    ## Windows 8.1
    If (-not $Config.ChooseProducts."Windows 8.1".x86 -and -not $Config.DeclineOptions.SystemType.x86){
        $LegacyNameFilterPath += "Windows 8.1--x86.txt"
    }
    ElseIf (-not $Config.ChooseProducts."Windows 8.1".x64 -and -not $Config.DeclineOptions.SystemType.x64){
        $LegacyNameFilterPath += "Windows 8.1--x64.txt"
    }
    ## システムの種類
    If ($Config.DeclineOptions.SystemType.x86){
        $LegacyNameFilterPath += "ALL--x86.txt"
    }
    If ($Config.DeclineOptions.SystemType.x64){
        $LegacyNameFilterPath += "ALL--x64.txt"
    }
    If ($Config.DeclineOptions.SystemType.arm64){
        $LegacyNameFilterPath += "ALL--arm64.txt"
    }

    If ($LegacyNameFilterPath.Count -ne 0){
        $DeclineChoosedFilters.LegacyNameFilterPath = $LegacyNameFilterPath
        $DeclineRules += $DeclineChoosedFilters
    }

    ## Microsoft Edge (Chromium)
    $DeclineChoosedFilters = Get-Content (Join-Path $PSScriptRoot "..\DeclineRules\Microsoft Edge.json") -Encoding UTF8 | ConvertFrom-Json
    $LegacyNameFilterPath = @()
    $LegacyNameFilterPath += Export-ChoosedFiltersPerMsEdge
    ### システムの種類
    If ($Config.DeclineOptions.SystemType.x86){
        $LegacyNameFilterPath += "ALL--x86.txt"
    }
    If ($Config.DeclineOptions.SystemType.x64){
        $LegacyNameFilterPath += "ALL--x64.txt"
    }
    If ($Config.DeclineOptions.SystemType.arm64){
        $LegacyNameFilterPath += "ALL--arm64.txt"
    }
    If ($LegacyNameFilterPath.Count -ne 0){
        $DeclineChoosedFilters.LegacyNameFilterPath = $LegacyNameFilterPath
        $DeclineRules += $DeclineChoosedFilters
    }

    If ($Config.DeclineOptions."Microsoft Edge".DeclineOldVersions){
        $DeclineChoosedFilters = Get-Content (Join-Path $PSScriptRoot "..\DeclineRules\Microsoft Edge.json") -Encoding UTF8 | ConvertFrom-Json
        $DeclineChoosedFilters.DeclineOldVersions = $True
        $LegacyNameFilterPath = Export-ChoosedFiltersPerMsEdge -DeclineOldVersions
        If ($LegacyNameFilterPath.Count -ne 0){
            $DeclineChoosedFilters.LegacyNameFilterPath = $LegacyNameFilterPath
            $DeclineRules += $DeclineChoosedFilters
        }
    }

    ## Office
    $DeclineChoosedFilters = Get-Content (Join-Path $PSScriptRoot "..\DeclineRules\Office.json") -Encoding UTF8 | ConvertFrom-Json
    $TitleFilterPath = @()
    If (-not $Config.DeclineOptions.Office.x86){
        $TitleFilterPath += "Office--x86.txt"
    }
    ElseIf (-not $Config.DeclineOptions.Office.x64){
        $TitleFilterPath += "Office--x64.txt"
    }

    If ($TitleFilterPath.Count -ne 0){
        $DeclineChoosedFilters.TitleFilterPath = $TitleFilterPath
        $DeclineRules += $DeclineChoosedFilters
    }

    ## 機能更新プログラム
    $DeclineChoosedFilters = Get-Content (Join-Path $PSScriptRoot "..\DeclineRules\Windows--Decline Feature updates.json") -Encoding UTF8 | ConvertFrom-Json
    $TitleFilterPath = @()

    If ($Config.DeclineOptions.FeatureUpdate.Volume){
        $TitleFilterPath += "Windows--business editions.txt"
    }
    ElseIf ($Config.DeclineOptions.FeatureUpdate.Retail){
        $TitleFilterPath += "Windows--consumer editions.txt"
    }

    If ($TitleFilterPath.Count -ne 0){
        $DeclineChoosedFilters.TitleFilterPath = $TitleFilterPath
        $DeclineRules += $DeclineChoosedFilters
    }

    ## 置き換えられた更新プロラム
    ## $MainWindow.FindName("DeclineSuperseedsUpdatesCheckBox").IsChecked

    $CurrentConfig.DeclineRules = $DeclineRules
    Return $CurrentConfig
}

Function Global:Set-RequiredConfigurationValues($Config){
    Function Initialize-Configuration($ConfigPath, $Name, $DefaultConfigPath, [Switch]$IsRoot, [Switch]$IsArray){
        Try{
            If (($ConfigPath | Get-Member -Name $Name).Count -eq 0){
                If ($IsRoot){
                    $ConfigPath = $ConfigPath | Select-Object *, $Name
                    $ConfigPath.$Name = [PSCustomObject]@{}
                    Write-Verbose "[Set-RequiredConfigurationValues] Config に $Name をルートとして追加しました"
                }
                If ($IsArray){
                    $ConfigPath = $ConfigPath | Select-Object *, $Name
                    $ConfigPath.$Name = @()
                    Write-Verbose "[Set-RequiredConfigurationValues] Config に $Name をルート配列として追加しました"
                }
                If ($DefaultConfigPath -ne $Null){
                    If (-not $IsArray -and -not $IsRoot){
                        $ConfigPath | Add-Member -MemberType NoteProperty -Name $Name -Value $DefaultConfigPath.$Name
                        Write-Verbose "[Set-RequiredConfigurationValues] Config の $Name に既定値を追加しました"
                    }
                    Else{
                        Write-Warning "[Set-RequiredConfigurationValues] Config の $Name に既定値を追加できませんでした: DefaultConfigPath はルートのため値は追加を追加できません"
                    }
                }
                ElseIf(-not $IsArray -and -not $IsRoot){
                    Write-Warning "[Set-RequiredConfigurationValues] Config の $Name に既定値を追加できませんでした: DefaultConfigPath に既定値の定義がありませんでした"
                }
            }
        }
        Catch{
            If ($IsRoot){
                Write-Warning "[Set-RequiredConfigurationValues] Config に $Name をルートとして追加できませんでした: $($_.Exception.Message))"
            }
            If ($IsArray){
                Write-Warning "[Set-RequiredConfigurationValues] Config に $Name をルート配列として追加できませんでした: $($_.Exception.Message)"
            }
            ElseIf ($DefaultConfigPath -ne $Null){
                Write-Warning "[Set-RequiredConfigurationValues] Config の $Name に既定値を追加できませんでした: $($_.Exception.Message)"
            }
        }
        Return $ConfigPath
    }
    # Config
    $Config = Initialize-Configuration -ConfigPath $Config -Name "Config" -IsRoot
    $Config.Config = Initialize-Configuration -ConfigPath $Config.Config -DefaultConfigPath $DefaultConfig.Config -Name "Name"
    $Config.Config = Initialize-Configuration -ConfigPath $Config.Config -DefaultConfigPath $DefaultConfig.Config -Name "AdminName"

    # Wsus
    $Config = Initialize-Configuration -ConfigPath $Config -Name "Wsus" -IsRoot
    $Config.Wsus = Initialize-Configuration -ConfigPath $Config.Wsus -DefaultConfigPath $DefaultConfig.Wsus -Name "Server"
    $Config.Wsus = Initialize-Configuration -ConfigPath $Config.Wsus -DefaultConfigPath $DefaultConfig.Wsus -Name "Port"
    $Config.Wsus = Initialize-Configuration -ConfigPath $Config.Wsus -DefaultConfigPath $DefaultConfig.Wsus -Name "UseSsl"
    $Config.Wsus = Initialize-Configuration -ConfigPath $Config.Wsus -DefaultConfigPath $DefaultConfig.Wsus -Name "PreferredCulture"
    $Config.Wsus = Initialize-Configuration -ConfigPath $Config.Wsus -DefaultConfigPath $DefaultConfig.Wsus -Name "IisWsusPoolPath"

    # UpdatesFindMode
    $Config = Initialize-Configuration -ConfigPath $Config -Name "UpdatesFindMode" -IsRoot
    $Config.UpdatesFindMode = Initialize-Configuration -ConfigPath $Config.UpdatesFindMode -DefaultConfigPath $DefaultConfig.UpdatesFindMode -Name "ApprovedStates"
    $Config.UpdatesFindMode = Initialize-Configuration -ConfigPath $Config.UpdatesFindMode -DefaultConfigPath $DefaultConfig.UpdatesFindMode -Name "MinimumDate"
    $Config.UpdatesFindMode = Initialize-Configuration -ConfigPath $Config.UpdatesFindMode -DefaultConfigPath $DefaultConfig.UpdatesFindMode -Name "MaximumRetry"
    $Config.UpdatesFindMode = Initialize-Configuration -ConfigPath $Config.UpdatesFindMode -DefaultConfigPath $DefaultConfig.UpdatesFindMode -Name "ForceHalfModePerMonthLength"

    # ChooseProducts
    $Config = Initialize-Configuration -ConfigPath $Config -Name "ChooseProducts" -IsRoot
    $Config.ChooseProducts = Initialize-Configuration -ConfigPath $Config.ChooseProducts -Name "Windows 11" -IsArray
    $Config.ChooseProducts = Initialize-Configuration -ConfigPath $Config.ChooseProducts -Name "Windows 10" -IsArray
    $Config.ChooseProducts = Initialize-Configuration -ConfigPath $Config.ChooseProducts -Name "Windows 8.1" -IsRoot
    $Config.ChooseProducts."Windows 8.1" = Initialize-Configuration -ConfigPath $Config.ChooseProducts."Windows 8.1" -DefaultConfigPath $DefaultConfig.ChooseProducts."Windows 8.1" -Name "x64"
    $Config.ChooseProducts."Windows 8.1" = Initialize-Configuration -ConfigPath $Config.ChooseProducts."Windows 8.1" -DefaultConfigPath $DefaultConfig.ChooseProducts."Windows 8.1" -Name "x86"
    $Config.ChooseProducts = Initialize-Configuration -ConfigPath $Config.ChooseProducts -Name "Microsoft Edge" -IsRoot
    $Config.ChooseProducts."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.ChooseProducts."Microsoft Edge" -DefaultConfigPath $DefaultConfig.ChooseProducts."Microsoft Edge" -Name "arm64"
    $Config.ChooseProducts."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.ChooseProducts."Microsoft Edge" -DefaultConfigPath $DefaultConfig.ChooseProducts."Microsoft Edge" -Name "x64"
    $Config.ChooseProducts."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.ChooseProducts."Microsoft Edge" -DefaultConfigPath $DefaultConfig.ChooseProducts."Microsoft Edge" -Name "x86"
    $Config.ChooseProducts.PSObject.Properties.Remove("*")

    # DeclineOptions
    $Config = Initialize-Configuration -ConfigPath $Config -Name "DeclineOptions" -IsRoot
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -Name "CleanupWizard" -IsRoot
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "CompressUpdate"
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "CleanupObsoleteUpdates"
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "CleanupObsoleteComputers"
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "CleanupUnneededContentFiles"
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "DeclineExpiredUpdates"
    $Config.DeclineOptions.CleanupWizard = Initialize-Configuration -ConfigPath $Config.DeclineOptions.CleanupWizard -DefaultConfigPath $DefaultConfig.DeclineOptions.CleanupWizard -Name "DeclineSupersededUpdates"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "ForceDeclineSupersededUpdates"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -Name "Office" -IsRoot
    $Config.DeclineOptions.Office = Initialize-Configuration -ConfigPath $Config.DeclineOptions.Office -DefaultConfigPath $DefaultConfig.DeclineOptions.Office -Name "x64"
    $Config.DeclineOptions.Office = Initialize-Configuration -ConfigPath $Config.DeclineOptions.Office -DefaultConfigPath $DefaultConfig.DeclineOptions.Office -Name "x86"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -Name "Microsoft Edge" -IsRoot
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "Beta"
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "Dev"
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "Stable"
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "ExtendedStable"
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "WebView2Runtime"
    $Config.DeclineOptions."Microsoft Edge" = Initialize-Configuration -ConfigPath $Config.DeclineOptions."Microsoft Edge" -DefaultConfigPath $DefaultConfig.DeclineOptions."Microsoft Edge" -Name "DeclineOldVersions"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -Name "SystemType" -IsRoot
    $Config.DeclineOptions.SystemType = Initialize-Configuration -ConfigPath $Config.DeclineOptions.SystemType -DefaultConfigPath $DefaultConfig.DeclineOptions.SystemType -Name "arm64"
    $Config.DeclineOptions.SystemType = Initialize-Configuration -ConfigPath $Config.DeclineOptions.SystemType -DefaultConfigPath $DefaultConfig.DeclineOptions.SystemType -Name "x64"
    $Config.DeclineOptions.SystemType = Initialize-Configuration -ConfigPath $Config.DeclineOptions.SystemType -DefaultConfigPath $DefaultConfig.DeclineOptions.SystemType -Name "x86"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -Name "FeatureUpdate" -IsRoot
    $Config.DeclineOptions.FeatureUpdate = Initialize-Configuration -ConfigPath $Config.DeclineOptions.FeatureUpdate -DefaultConfigPath $DefaultConfig.DeclineOptions.FeatureUpdate -Name "Volume"
    $Config.DeclineOptions.FeatureUpdate = Initialize-Configuration -ConfigPath $Config.DeclineOptions.FeatureUpdate -DefaultConfigPath $DefaultConfig.DeclineOptions.FeatureUpdate -Name "Retail"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "IgnoreWindows10Version1809AndEarlier"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "DynamicUpdate"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "FeatureOnDemand"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "LanguagePack"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "WindowsServer"
    $Config.DeclineOptions = Initialize-Configuration -ConfigPath $Config.DeclineOptions -DefaultConfigPath $DefaultConfig.DeclineOptions -Name "InsiderPreview"
    $Config.DeclineOptions.PSObject.Properties.Remove("*")

    # DeclineRules
    $Config = Initialize-Configuration -ConfigPath $Config -Name "DeclineRules" -IsArray

    $Config.DeclineRules = $Config.DeclineRules | Select-Object *, @{Name="LegacyNameFilter";Expression={$Null}}, @{Name="TitleFilter";Expression={$Null}}
    ForEach($DeclineRule in $Config.DeclineRules){
        $LogFileNameBase = $DeclineRule.LogFileNameBase
        If ($DeclineRule.LegacyNameFilterPath -ne $Null){
            $DeclineRule.LegacyNameFilter = @()
            $DeclineRule.LegacyNameFilterPath | Out-String -Stream | Where-Object {
                $LegacyNameFilterPath = $_
                If (-not (Test-Path $_ -PathType Leaf)){
                    $LegacyNameFilterPath = Join-Path $LegacyNameFiltersDirectory $LegacyNameFilterPath
                }
                If (Test-Path $LegacyNameFilterPath -PathType Leaf){
                    $DeclineRule.LegacyNameFilter += (Get-Content -Path $LegacyNameFilterPath -Encoding UTF8)
                }
                Else{
                    Write-Warning "[$LogFileNameBase] $LegacyNameFilterPath が見つかりませんでした"
                }
            }
            $DeclineRule.LegacyNameFilter = (($DeclineRule.LegacyNameFilter | Out-String -Stream | Where-Object{($_.IndexOf("##") -ne -1) -or ($_.IndexOf("#") -ne 0) -and (-not [string]::IsNullOrWhiteSpace($_))}) -join "`n") -replace "##", "#"
        }ElseIf ($DeclineRule.TitleFilterPath -ne $Null){
            $DeclineRule.TitleFilter = @()
            $DeclineRule.TitleFilterPath | Out-String -Stream | Where-Object {
                $TitleFilterPath = $_
                If (-not (Test-Path $_ -PathType Leaf)){
                    $TitleFilterPath = Join-Path $TitleFiltersDirectory $TitleFilterPath
                }
                If (Test-Path $TitleFilterPath -PathType Leaf){
                    $DeclineRule.TitleFilter += (Get-Content -Path $TitleFilterPath -Encoding UTF8)
                }
                Else{
                    Write-Warning "[$LogFileNameBase] $TitleFilterPath が見つかりませんでした"
                }
            }
            $DeclineRule.TitleFilter = (($DeclineRule.TitleFilter | Out-String -Stream | Where-Object{($_.IndexOf("##") -ne -1) -or ($_.IndexOf("#") -ne 0) -and (-not [string]::IsNullOrWhiteSpace($_))}) -join "`n") -replace "##", "#"
        }
    }
    $Config.ChooseProducts.PSObject.Properties.Remove("*")

    # ApproveRule
    $Config = Initialize-Configuration -ConfigPath $Config -Name "ApproveRule" -IsArray

    # MaintenanceSql
    $Config = Initialize-Configuration -ConfigPath $Config -Name "MaintenanceSql" -IsRoot
    $Config.MaintenanceSql = Initialize-Configuration -ConfigPath $Config.MaintenanceSql -DefaultConfigPath $DefaultConfig.MaintenanceSql -Name "SqlCmdPath"
    $Config.MaintenanceSql = Initialize-Configuration -ConfigPath $Config.MaintenanceSql -DefaultConfigPath $DefaultConfig.MaintenanceSql -Name "ServerInstancePath"
    $Config.MaintenanceSql = Initialize-Configuration -ConfigPath $Config.MaintenanceSql -DefaultConfigPath $DefaultConfig.MaintenanceSql -Name "ScriptPath"
    $Config.MaintenanceSql = Initialize-Configuration -ConfigPath $Config.MaintenanceSql -DefaultConfigPath $DefaultConfig.MaintenanceSql -Name "SqlCmdExeMode"

    $UpdateServiceInstalledRoleServicesPath = "HKLM:\\SOFTWARE\Microsoft\Update Services\Server\Setup\Installed Role Services"
    If ([String]::IsNullOrEmpty($Config.MaintenanceSql.ServerInstancePath) -and (Test-Path $UpdateServiceInstalledRoleServicesPath)){
        #
    }

    If ([String]::IsNullOrEmpty($Config.MaintenanceSql.SqlCmdExeMode) -or -not $Config.MaintenanceSql.SqlCmdExeMode -in @("psmodule","exe")){
        Try{
            Import-Module SqlServer -ErrorAction Stop
            $Config.MaintenanceSql.SqlCmdExeMode = "psmodule"
        }
        Catch{
            $Config.MaintenanceSql.SqlCmdExeMode = "exe"
        }
        Write-Verbose "[Set-RequiredConfigurationValues] Config.MaintenanceSql.SqlCmdExeMode を $($Config.MaintenanceSql.SqlCmdExeMode) に変更しました"
    }

    # ScheduledTask
    $Config = Initialize-Configuration -ConfigPath $Config -Name "ScheduledTask" -IsRoot
    $Config.ScheduledTask = Initialize-Configuration -ConfigPath $Config.ScheduledTask -DefaultConfigPath $DefaultConfig.ScheduledTask -Name "Name"

    # WizardView
    $Config = Initialize-Configuration -ConfigPath $Config -Name "WizardView" -IsRoot
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "DetectiveInstalledComponents"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowOptionTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowServerTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowSyncWindowsProductsTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowDeclineRuleTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowApproveRuleOptionsTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowScheduleTab"
    $Config.WizardView = Initialize-Configuration -ConfigPath $Config.WizardView -DefaultConfigPath $DefaultConfig.WizardView -Name "ShowAboutTab"

    # Log
    $Config = Initialize-Configuration -ConfigPath $Config -Name "Log" -IsRoot
    $Config.Log = Initialize-Configuration -ConfigPath $Config.Log -DefaultConfigPath $DefaultConfig.Log -Name "IsLogging"
    $Config.Log = Initialize-Configuration -ConfigPath $Config.Log -DefaultConfigPath $DefaultConfig.Log -Name "MaximumCount"
    $Config.Log = Initialize-Configuration -ConfigPath $Config.Log -DefaultConfigPath $DefaultConfig.Log -Name "Verbose"

    # RequiresVersion
    $Config = Initialize-Configuration -ConfigPath $Config -DefaultConfigPath $DefaultConfig -Name "RequiresVersion"

    Return $Config
}