Home > Windows にまつわる e.t.c.

フルオートでWindows Updateする


新規構築した Windows 環境に対して Windows Update するのは、何度も再起動が必要なので手間がかかります。

でも、この PowerShell スクリプトを使うと、再起動が不要になるまで Windows Update と再起動を自動で繰り返すので、放置しておけば Windows Update が完了するという手間いらず !!

スクリプトの実行ログは C:\WU_Log に出力されます。

動作環境は Windows 7 / Windows Server 2008 R2 以降です。

 

使い方

C:\WindowsUpdate を作成し、スクリプト(AutoWindowsUpdate.ps1)を置いて管理権限で実行します。
引数に「 Full 」を与えると全ての更新を適用し、引数なしだと重要な更新のみを適用します。

C:\WindowsUpdate\AutoWindowsUpdate.ps1 Full

 

実行ログに "=-=-=-=-=- Windows Update finished -=-=-=-=-=" が出力されるまで放置します(環境にもよりますが Windows Server 2012 R2 Update 1 の初 Full で 3 時間くらい)
そのまま使っていると、予告もなく再起動が入るので危険です。

以下スクリプトを PowerShell プロンプトにコピペすれば最新の Windows Update 実行ログが表示されるので、テキストエディタでログ開かなくても簡単に確認できます。

$NewestLog = dir C:\WU_Log\*.log | sort LastWriteTime -Descending | Select -First 1
Get-Content $NewestLog.FullName

 

会話式の更新(Windows Defenderのパターンファイルとか)は更新が適用されないので、最後に手動 Windows Update する必要がありますが、これは短時間で終わります。

Windows Server の場合、役割/機能を追加すると更新が増えるので、環境構築完了後に Windows Update することをお勧めします。

 

既知の問題と対策

30分以上待っても処理が進まない事があります。この対策は、Windows Update クライアントを更新すると改善します。
(Windows Update クライアントは、Windows Update で配布されるのですが、初めての Windows Update だとこれが古いままなので手動で最新に更新します)

Windows Update クライアントは以下キーワードで検索して最新版をダウンロードします。

Windows Update クライアント site:support.microsoft.com

 

ちなみに、これを書いているときの最新は以下の KB です。

Windows 7 および Windows Server 2008 R2 用 Windows Update クライアント: 2016 年 3 月
https://support.microsoft.com/ja-jp/kb/3138612

Windows Update Client for Windows 8.1 and Windows Server 2012 R2: February 2016
https://support.microsoft.com/ja-jp/kb/3135449

 

 

スクリプト

AutoWindowsUpdate.ps1

<#
.SYNOPSIS
Windows Update と再起動を自動実行します

<CommonParameters> はサポートしていません

.DESCRIPTION
・フルアップデート(-Option Full)
    全ての更新プログラムを適用します

・ミニマムアップデート(-Option Minimum)
    重要な更新プログラムのみを適用します
    オプションを省略した場合はこのモードになります

.EXAMPLE
PS C:\WindowsUpdate> .\AutoWindowsUpdate.ps1 Full

全ての更新プログラムを適用

.EXAMPLE
PS C:\WindowsUpdate> .\AutoWindowsUpdate.ps1

重要な更新プログラムのみを適用

.PARAMETER Option
操作モード
    Full: 全ての更新プログラムを適用
    Minimum: 重要な更新プログラムのみを適用
    省略: 重要な更新プログラムのみを適用

<CommonParameters> はサポートしていません

.LINK
http://www.vwnet.jp/Windows/PowerShell/FullAutoWU.htm
#>

##########################################################################
#
# Windows Update PowerShell
#
#  C:\WindowsUpdate にスクリプトを置いて実行する
#
#   参考サイト: http://yamanxworld.blogspot.jp/2010/07/windows-scripting-windows-update_05.html
#
##########################################################################
param (
        [ValidateSet("Full", "Minimum")][string]$Option # アップデートオプション
    )

# スクリプトの配置場所
$G_MyName = "C:\WindowsUpdate\AutoWindowsUpdate.ps1"

# 最大適用更新数
$G_MaxUpdateNumber = 100

$G_LogPath = "C:\WU_Log"
$G_LogName = "WU_Log.txt"
##########################################################################
# ログ出力
##########################################################################
function Log(
            $LogString
            ){

    $Now = Get-Date

    $Log = "{0:0000}-{1:00}-{2:00} " -f $Now.Year, $Now.Month, $Now.Day
    $Log += "{0:00}:{1:00}:{2:00}.{3:000} " -f $Now.Hour, $Now.Minute, $Now.Second, $Now.Millisecond
    $Log += $LogString

    if( $G_LogName -eq $null ){
        $G_LogName = "LOG"
    }

    $LogFile = $G_LogName +"_{0:0000}-{1:00}-{2:00}.log" -f $Now.Year, $Now.Month, $Now.Day

    # ログフォルダーがなかったら作成
    if( -not (Test-Path $G_LogPath) ) {
        New-Item $G_LogPath -Type Directory
    }

    $LogFileName = Join-Path $G_LogPath $LogFile

    Write-Output $Log | Out-File -FilePath $LogFileName -Encoding Default -append

    Return $Log
}

##########################################################################
# レジストリ追加/更新
##########################################################################
function RegSet( $RegPath, $RegKey, $RegKeyType, $RegKeyValue ){
    # レジストリそのものの有無確認
    $Elements = $RegPath -split "\\"
    $RegPath = ""
    $FirstLoop = $True
    foreach ($Element in $Elements ){
        if($FirstLoop){
            $FirstLoop = $False
        }
        else{
            $RegPath += "\"
        }
        $RegPath += $Element
        if( -not (test-path $RegPath) ){
            Log "Add Registry : $RegPath"
            md $RegPath
        }
    }

    # Key有無確認
    $Result = Get-ItemProperty $RegPath -name $RegKey -ErrorAction SilentlyContinue
    # キーがあった時
    if( $Result -ne $null ){
        Set-ItemProperty $RegPath -name $RegKey -Value $RegKeyValue
    }
    # キーが無かった時
    else{
        # キーを追加する
        New-ItemProperty $RegPath -name $RegKey -PropertyType $RegKeyType -Value $RegKeyValue
    }
    Get-ItemProperty $RegPath -name $RegKey
}

##########################################################################
# Autoexec.ps1 有効
##########################################################################
function EnableAutoexec( $ScriptName, $Option ){
    if( -not (Test-Path $ScriptName)){
        Log "[FAIL] $ScriptName not found !!"
        exit
    }

    ### boot 時に autoexec.ps1 を自動実行するレジストリ設定

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0"
    $RegKey = "FileSysPath"
    $RegKeyType = "String"
    $RegKeyValue = "C:\\Windows\\System32\\GroupPolicy\\Machine"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "PSScriptOrder"
    $RegKeyType = "DWord"
    $RegKeyValue = 3
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0"
    $RegKey = "Script"
    $RegKeyType = "String"
    $RegKeyValue = "autoexec.ps1"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "Parameters"
    $RegKeyType = "String"
    $RegKeyValue = "$Option"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "IsPowershell"
    $RegKeyType = "DWord"
    $RegKeyValue = 1
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0"
    $RegKey = "FileSysPath"
    $RegKeyType = "String"
    $RegKeyValue = "C:\\Windows\\System32\\GroupPolicy\\Machine"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "PSScriptOrder"
    $RegKeyType = "DWord"
    $RegKeyValue = 3
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0\0"
    $RegKey = "Script"
    $RegKeyType = "String"
    $RegKeyValue = "autoexec.ps1"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "Parameters"
    $RegKeyType = "String"
    $RegKeyValue = "$Option"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    ### 自動実行するスクリプトを autoexec.ps1 に上書きコピー
    $TergetPath = "C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup"
    $TergetFile = Join-Path $TergetPath "autoexec.ps1"
    Log "$ScriptName → $TergetFile"
    if( -not (Test-Path $TergetPath)){
        md $TergetPath
        Log "md $TergetPath"
    }
    copy $ScriptName $TergetFile -Force

    Log "[INFO] $ScriptName → $TergetFile copied"

    if( -not (Test-Path $TergetFile)){
        Log "[FAIL] autoexec.ps1 copy failed !!"
        exit
    }
}

##########################################################################
# Autoexec.ps1 無効
##########################################################################
function DisableAutoexec(){
    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0"
    if(Test-Path $RegPath){
        Remove-Item $RegPath -Recurse -Force -Confirm:$false
    }

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0"
    if(Test-Path $RegPath){
        Remove-Item $RegPath -Recurse -Force -Confirm:$false
    }

    $Terget = "c:\Windows\System32\GroupPolicy\Machine\Scripts\Startup\autoexec.ps1"
    if(Test-Path $Terget){
        del $Terget -Force
    }
    Log "[INFO] Autoexec Disabled."}


##########################################################################
#
# main
#
##########################################################################
if (-not(([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))) {
    Log "実行には管理権限が必要です"
    exit
}

# 自動起動スクリプト停止
DisableAutoexec

# バージョン確認
$OSData = Get-WmiObject Win32_OperatingSystem
$BuildNumber = $OSData.BuildNumber
$strVersion = $OSData.Version
$strVersion = $strVersion.Replace( ".$BuildNumber", "" )
$Version = [decimal]$strVersion
if( $Version -lt 6.1 ){
    Log "Windows Server 2008 R2 / Windows 7 以降しかサポートしていません"
    exit
}

# スクリプト存在確認
if( -not(Test-Path $G_MyName )){
    Log "スクリプトを $G_MyName に置いて実行してください"
    exit
}

# 既知の問題(KB2962824)対応
if(($Version -ge 6.3) -and ($Version -lt 6.4)){
    $OSData = Get-WmiObject Win32_OperatingSystem
    if( $OSData.Caption -match "Windows Server 2012 R2" ){
        Log "Windows Server 2012 R2"
        $OriginalProgressPreference = $ProgressPreference
        $ProgressPreference="SilentlyContinue"
        $BitLocker = Get-WindowsFeature BitLocker
        if( $BitLocker.Installed -eq $false ){
            Log "BitLocker がインストールされていないのでインストール & 再起動"
            EnableAutoexec $G_MyName $Option
            Add-WindowsFeature BitLocker -Restart
        }
        $ProgressPreference = $OriginalProgressPreference
    }
}

Log "--- Running Windows Update ---"
Log "Searching for updates..."
$updateSession = new-object -com "Microsoft.Update.Session"

$updateSearcher = $updateSession.CreateupdateSearcher()

# アップデートタイプコントロール
if( $Option -match "ful" ){
    Log "Full Update"
    $Option = "Full"
    $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software'")
}
else{
    Log "Minimum Update"
    $Option = "Minimum"
    $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software' and AutoSelectOnWebSites=1")
}


Log "List of applicable items on the machine:"
if ($searchResult.Updates.Count -eq 0) {
    Log "There are no applicable updates."
    Log "=-=-=-=-=- Windows Update finished -=-=-=-=-="
}
else{
    $downloadReq = $False
    $i = 0
    foreach ($update in $searchResult.Updates){
        $i++
        if ( $update.IsDownloaded ) {
            $UpdateTitol = $update.Title
            Log "$i : $UpdateTitol (downloaded)"
        }
        else
        {
            $downloadReq = $true
            $UpdateTitol = $update.Title
            Log "$i : $UpdateTitol (not downloaded)"
        }
    }
    if ( $downloadReq ) {
        Log "Creating collection of updates to download..."
        $updatesToDownload = new-object -com "Microsoft.Update.UpdateColl"
        foreach ($update in $searchResult.Updates){
            $updatesToDownload.Add($update) | out-null
        }
        Log "Downloading updates..."
        $downloader = $updateSession.CreateUpdateDownloader()
        $downloader.Updates = $updatesToDownload
        $downloader.Download()
        Log "List of downloaded updates:"
        $i = 0
        foreach ($update in $searchResult.Updates){
            $i++
            if ( $update.IsDownloaded ) {
                $UpdateTitol = $update.Title
                Log "$i : $UpdateTitol (downloaded)"
            }
            else
            {
                $UpdateTitol = $update.Title
                Log "$i : $UpdateTitol (not downloaded)"
            }
        }
    }
    else
    {
        Log "All updates are already downloaded."
    }
    $updatesToInstall = new-object -com "Microsoft.Update.UpdateColl"
    Log "Creating collection of downloaded updates to install..."
    $i = 0
    foreach ($update in $searchResult.Updates){
        if ( $update.IsDownloaded ) {
            $updatesToInstall.Add($update) | out-null
            $i++
            $UpdateTitol = $update.Title
            Log "$i / $G_MaxUpdateNumber : $UpdateTitol (Install)"
            if( $i -ge $G_MaxUpdateNumber ){
                Log "Break max update $G_MaxUpdateNumber"
                break
            }
        }
    }
    if ( $updatesToInstall.Count -eq 0 ) {
        Log "Not ready for installation."
        Log "=-=-=-=-=- Windows Update Abnormal End -=-=-=-=-="
    }
    else
    {
        $InstallCount = $updatesToInstall.Count
        Log "Installing $InstallCount updates..."
        $installer = $updateSession.CreateUpdateInstaller()
        $installer.Updates = $updatesToInstall
        $installationResult = $installer.Install()
        if ( $installationResult.ResultCode -eq 2 ) {
            Log "All updates installed successfully."
        }
        else
        {
            Log "Some updates could not installed."
        }
        if ( $installationResult.RebootRequired ) {
            Log "One or more updates are requiring reboot."

            Log "[INFO] Autoexec Enabled"
            EnableAutoexec $G_MyName $Option
            sleep 30
            Log "Reboot system now !!"
            Restart-Computer -Force
        }
        else
        {
            Log "Finished. Reboot are not required."
            Log "=-=-=-=-=- Windows Update finished -=-=-=-=-="
        }
    }
}

一度に多くの更新を適用すると、ロールバックが発生することがあるので、一度に適用する更新を100に制限するようにした(2015/07/12)
既知の問題(KB2962824)対応 (2015/09/29)

 

スクリプトのダウンロード

スクリプトをコピペして作るのが面倒な方は、管理者権限で以下スクリプトを実行すればダウンロードできます(コード署名付き 思った効果が無いことが分かったのでコード署名やめました)
PowerShell 3.0 な方は wget ではなく Invoke-WebRequest (Alias 入っていなかったはず)

if(-not (Test-Path C:\WindowsUpdate)){ md C:\WindowsUpdate }
wget http://www.vwnet.jp/Windows/PowerShell/ps1/autowindowsupdate.txt -OutFile C:\WindowsUpdate\AutoWindowsUpdate.ps1

 

ダウンロードした .ps1 の SHA256 のハッシュ値は以下です。

04FB68B37F227FB86DA01060B13AD68B8817227902A9B167B4B4F8A8212360BA

 

PowerShell Ver. 4 以降であれば、PowerShell でハッシュ確認できます

(Get-FileHash C:\WindowsUpdate\AutoWindowsUpdate.ps1 -Algorithm SHA256).Hash -eq "04FB68B37F227FB86DA01060B13AD68B8817227902A9B167B4B4F8A8212360BA"

 

スクリプトダウンロードと Windows Update を一気にするのなら、以下スクリプトを管理権限 PowerShell プロンプトにコピペします。

if(-not (Test-Path C:\WindowsUpdate)){ md C:\WindowsUpdate }
wget http://www.vwnet.jp/Windows/PowerShell/ps1/autowindowsupdate.txt -OutFile C:\WindowsUpdate\AutoWindowsUpdate.ps1
if( (Get-FileHash C:\WindowsUpdate\AutoWindowsUpdate.ps1 -Algorithm SHA256).Hash -eq "04FB68B37F227FB86DA01060B13AD68B8817227902A9B167B4B4F8A8212360BA" ){
C:\WindowsUpdate\AutoWindowsUpdate.ps1 full }

 

補助スクリプト

運用していて補助スクリプトが必要になったので追加で作りました。

機能は、AutoWindowsUpdate.ps1 を自動起動にセットして reboot するスクリプトです。

どんな時に使うかというと...

・いつまでも PowerShell プロンプト開いたままにしたくない
・リモートコンピューターに WU をかける

こんな用途で使います。

<#
.SYNOPSIS
Windows Update スクリプトを投入し再起動します
PowerShell プロンプトを閉じないように注意する必要がありません

<CommonParameters	> はサポートしていません

.DESCRIPTION
・フルアップデート(-Option Full)
    全ての更新プログラムを適用します

・ミニマムアップデート(-Option Minimum)
    重要な更新プログラムのみを適用します
    オプションを省略した場合はこのモードになります

.EXAMPLE
PS C:\WindowsUpdate> .\SubmitWU.ps1 Full

全ての更新プログラムを適用

.EXAMPLE
PS C:\WindowsUpdate> .\SubmitWU.ps1

重要な更新プログラムのみを適用

.PARAMETER Option
操作モード
    Full: 全ての更新プログラムを適用
    Minimum: 重要な更新プログラムのみを適用
    省略: 重要な更新プログラムのみを適用

<CommonParameters> はサポートしていません

.LINK
http://www.vwnet.jp/Windows/PowerShell/FullAutoWU.htm
#>


##########################################################################
#
# Windows Update PowerShell 投入
#
#   参考サイト: http://yamanxworld.blogspot.jp/2010/07/windows-scripting-windows-update_05.html
#
##########################################################################
param (
        [ValidateSet("Full", "Minimum")][string]$Option # アップデートオプション
    )

# スクリプトの配置場所
$G_MyName = "C:\WindowsUpdate\AutoWindowsUpdate.ps1"

# 最大適用更新数
$G_MaxUpdateNumber = 100

$G_LogPath = "C:\WU_Log"
$G_LogName = "WU_Log.txt"
##########################################################################
# ログ出力
##########################################################################
function Log(
            $LogString
            ){

    $Now = Get-Date

    $Log = "{0:0000}-{1:00}-{2:00} " -f $Now.Year, $Now.Month, $Now.Day
    $Log += "{0:00}:{1:00}:{2:00}.{3:000} " -f $Now.Hour, $Now.Minute, $Now.Second, $Now.Millisecond
    $Log += $LogString

    if( $G_LogName -eq $null ){
        $G_LogName = "LOG"
    }

    $LogFile = $G_LogName +"_{0:0000}-{1:00}-{2:00}.log" -f $Now.Year, $Now.Month, $Now.Day

    # ログフォルダーがなかったら作成
    if( -not (Test-Path $G_LogPath) ) {
        New-Item $G_LogPath -Type Directory
    }

    $LogFileName = Join-Path $G_LogPath $LogFile

    Write-Output $Log | Out-File -FilePath $LogFileName -Encoding Default -append

    Return $Log
}

##########################################################################
# レジストリ追加/更新
##########################################################################
function RegSet( $RegPath, $RegKey, $RegKeyType, $RegKeyValue ){
    # レジストリそのものの有無確認
    $Elements = $RegPath -split "\\"
    $RegPath = ""
    $FirstLoop = $True
    foreach ($Element in $Elements ){
        if($FirstLoop){
            $FirstLoop = $False
        }
        else{
            $RegPath += "\"
        }
        $RegPath += $Element
        if( -not (test-path $RegPath) ){
            Log "Add Registry : $RegPath"
            md $RegPath
        }
    }

    # Key有無確認
    $Result = Get-ItemProperty $RegPath -name $RegKey -ErrorAction SilentlyContinue
    # キーがあった時
    if( $Result -ne $null ){
        Set-ItemProperty $RegPath -name $RegKey -Value $RegKeyValue
    }
    # キーが無かった時
    else{
        # キーを追加する
        New-ItemProperty $RegPath -name $RegKey -PropertyType $RegKeyType -Value $RegKeyValue
    }
    Get-ItemProperty $RegPath -name $RegKey
}

##########################################################################
# Autoexec.ps1 有効
##########################################################################
function EnableAutoexec( $ScriptName, $Option ){
    if( -not (Test-Path $ScriptName)){
        Log "[FAIL] $ScriptName not found !!"
        exit
    }

    ### boot 時に autoexec.ps1 を自動実行するレジストリ設定

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0"
    $RegKey = "FileSysPath"
    $RegKeyType = "String"
    $RegKeyValue = "C:\\Windows\\System32\\GroupPolicy\\Machine"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "PSScriptOrder"
    $RegKeyType = "DWord"
    $RegKeyValue = 3
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0"
    $RegKey = "Script"
    $RegKeyType = "String"
    $RegKeyValue = "autoexec.ps1"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "Parameters"
    $RegKeyType = "String"
    $RegKeyValue = "$Option"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "IsPowershell"
    $RegKeyType = "DWord"
    $RegKeyValue = 1
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0"
    $RegKey = "FileSysPath"
    $RegKeyType = "String"
    $RegKeyValue = "C:\\Windows\\System32\\GroupPolicy\\Machine"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "PSScriptOrder"
    $RegKeyType = "DWord"
    $RegKeyValue = 3
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0\0"
    $RegKey = "Script"
    $RegKeyType = "String"
    $RegKeyValue = "autoexec.ps1"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    $RegKey = "Parameters"
    $RegKeyType = "String"
    $RegKeyValue = "$Option"
    RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

    ### 自動実行するスクリプトを autoexec.ps1 に上書きコピー
    $TergetPath = "C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup"
    $TergetFile = Join-Path $TergetPath "autoexec.ps1"
    Log "$ScriptName → $TergetFile"
    if( -not (Test-Path $TergetPath)){
        md $TergetPath
        Log "md $TergetPath"
    }
    copy $ScriptName $TergetFile -Force

    Log "[INFO] $ScriptName → $TergetFile copied"

    if( -not (Test-Path $TergetFile)){
        Log "[FAIL] autoexec.ps1 copy failed !!"
        exit
    }
}

##########################################################################
# Autoexec.ps1 無効
##########################################################################
function DisableAutoexec(){
    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0"
    if(Test-Path $RegPath){
        Remove-Item $RegPath -Recurse -Force -Confirm:$false
    }

    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0"
    if(Test-Path $RegPath){
        Remove-Item $RegPath -Recurse -Force -Confirm:$false
    }

    $Terget = "c:\Windows\System32\GroupPolicy\Machine\Scripts\Startup\autoexec.ps1"
    if(Test-Path $Terget){
        del $Terget -Force
    }
    Log "[INFO] Autoexec Disabled."}


##########################################################################
#
# main
#
##########################################################################
if (-not(([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))) {
    Log "実行には管理権限が必要です"
    exit
}

# 自動起動スクリプト停止
DisableAutoexec

$OSData = Get-WmiObject Win32_OperatingSystem
$BuildNumber = $OSData.BuildNumber
$strVersion = $OSData.Version
$strVersion = $strVersion.Replace( ".$BuildNumber", "" )
$Version = [decimal]$strVersion
if( $Version -lt 6.1 ){
    Log "Windows Server 2008 R2 / Windows 7 以降しかサポートしていません"
    exit
}

# スクリプト存在確認
if( -not (Test-Path $G_MyName)){
    Log "[FAIL] $G_MyName not found !!"
    exit
}

Log "--- Submit Windows Update ---"

# アップデートタイプコントロール
if( $Option -match "ful" ){
    Log "Full Update"
    $Option = "Full"
}
else{
    Log "Minimum Update"
    $Option = "Minimum"
}

# 既知の問題(KB2962824)対応
if(($Version -ge 6.3) -and ($Version -lt 6.4)){
    $OSData = Get-WmiObject Win32_OperatingSystem
    if( $OSData.Caption -match "Windows Server 2012 R2" ){
        Log "Windows Server 2012 R2"
        $OriginalProgressPreference = $ProgressPreference
        $ProgressPreference="SilentlyContinue"
        $BitLocker = Get-WindowsFeature BitLocker
        if( $BitLocker.Installed -eq $false ){
            Log "BitLocker がインストールされていないのでインストール & 再起動"
            Add-WindowsFeature BitLocker
        }
        $ProgressPreference = $OriginalProgressPreference
    }
}

EnableAutoexec $G_MyName $Option
sleep 30
Log "Reboot system now !!"
Restart-Computer -Force

 

ダウンロードとハッシュ値は以下になります。

if(-not (Test-Path C:\WindowsUpdate)){ md C:\WindowsUpdate }
wget http://www.vwnet.jp/Windows/PowerShell/ps1/SubmitWU.txt -OutFile C:\WindowsUpdate\SubmitWU.ps1

SHA256 のハッシュ値
59FCD152440804103C5BF609821F8FF622E93B0CB67A2217493A72EA180AAD5F

 

 

関連情報

Windows Server 2016 インストール メディア に KB を適用する
http://www.vwnet.jp/Windows/WS16/2016101001/OfflineKBInstall4InstallISO.htm

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.