9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PowerShellAdvent Calendar 2016

Day 8

PowershellDSCでWindowsUpdateを制御

Last updated at Posted at 2016-09-30

複数台あるAzureの仮想マシンの管理をPowerShellDSCで行っています。
十分にテストしてからWindowsUpdateを取り込む必要がありました。
そこである特定期間までのWindowsUpdateを取り込むというスクリプトを作りました。

#PSWindowsUpdateモジュール
PSWindowsUpdateというパッケージを使いました。楽したつもりがパッケージのインストールに手間取ってしまいました
以下に思いついたパッケージの導入方法をあげていきます。
##PowershellGallery版
###WMF5.0環境でInstall-Moduleで取り込む
https://www.powershellgallery.com/packages/PSWindowsUpdate/1.5.2.2
各ノードに5.0を導入するのに格式が高そうだったので断念。
##scriptcenter版
###事前にダウンロードしておいて取り込む
https://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc
二度手間になるため断念しました。あとになって思えば初めからこれにしておけばよかったと後悔しています。
##chocolatey版
###4.0環境でもコマンドだけで取り込み可能
https://chocolatey.org/packages/PSWindowsUpdate
chocalteyが簡単そうだったので採用しました。
しかしDSCではなぜかchocolateyのインストールがうまくいきませんでした。
結果的に、一度Pathを通しておいて再度インストールすればなんとかインストールできることがわかりました。
#実際のコードの一部

Invoke-WUScript.psm1
function Set-TargetResource
{
    [CmdletBinding()]
    param
	(
		[parameter(Mandatory = $true)]
		[ValidateSet("InvokeWUScript")]
		[System.String]
		$Name,

		[System.DateTime]
		$LastUpdateDatetime,

		[System.String[]]
		$KBArticleID,

		[System.Boolean]
		$OrLater
	)
    #モジュールがインストールされているかチェック
    ChkPSWU >$null

    Set-StrictMode -Version Latest

    #Invoke Main function
    Main -LastUpdateDatetime $LastUpdateDatetime `
         -KB $KBArticleID `
         -OrLater $OrLater

}

function Main
{
    [CmdletBinding()]
    param(
        [System.DateTime]
        $LastUpdateDatetime,
        [System.String[]]
        $KB,
        [System.Boolean]
        $OrLater
    )
    if($null -ne $KB) {
        Write-Verbose "Updates to specify the ID"
        #直接KBを指定した場合はチェック無しでインストールさせる
        Get-WUInstall -KBArticleID $KB -AutoReboot -AcceptAll
    }elseif ($null -ne $LastUpdateDatetime) {
        
        Write-Verbose "Updates to specify the date" 
        #日付が入っていれば、その日までの更新を取り込む
        $PatchList = Get-WUList
        if($OrLater){
            #指定日以降の更新のみに絞る
            $PatchList = $PatchList | where {$_.LastDeploymentChangeTime -ge $LastUpdateDatetime}
        }else{
            #指定日以前の更新のみに絞る
            $PatchList = $PatchList | where {$_.LastDeploymentChangeTime -le $LastUpdateDatetime}
        }
        
        if($null -ne $PatchList)
        {
            $PatchCounter = $PatchList.Count
            Write-Verbose "$PatchCounter of the update found"
            #if($PatchCounter -ge 1) {
            $MatchedPatchList = [string[]]($PatchList | select -Expand KB)
            Get-WUInstall -KBArticleID $MatchedPatchList -AutoReboot -AcceptAll
            #}
        }

    } else {
        throw "Parameter Not Found Error"
    }
}

function ChkPSWU
{
    try
    {        
        Write-Verbose "PSWindowsUpdateの存在チェック"
        Import-Module PSWindowsUpdate -Force -ErrorAction Stop -Verbose
    }
    catch
    {
        try
        {
            InstallPsWUModule
        }
        catch
        {
            
            try{
                #必要なモジュールのインストール
                InstallChoco
                InstallPsWUModule
            }
            catch
            {
                Write-Verbose $error[0].exception
                throw "PSWindowsUpdateのモジュールが存在しません。カスタムスクリプトまたは手動でインストールしてください。" 
            }
        }
    }
}
function InstallPsWUModule
{
    #なければインストール
    Write-Verbose "PSWindowsUpdateのインストール"
    choco Install PSWindowsUpdate -y
    
    Write-Verbose "PSWindowsUpdateモジュールのインポート"
    Import-Module PSWindowsUpdate -Force -ErrorAction Stop -Verbose
}
function InstallChoco
{
    try
    {
        Write-Verbose "chocolateyのインストール"
        (iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')))>$null 2>&1
    }
    catch
    {
        Write-Verbose "Pathを設定した上で再度インストール"
        Write-Verbose "chocolateyの環境変数を無理やり追加"
        $path = [Environment]::GetEnvironmentVariable('PATH', 'Machine')
        $path += ';' + 'C:\ProgramData\chocolatey\bin'
        [Environment]::SetEnvironmentVariable('PATH', $path, 'Machine')
        Write-Verbose "chocolateyのインストール"
        (iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')))>$null 2>&1
    }
}
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?