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

OS起動時に PowerShell スクリプトを自動実行する


Windows Server を構築する際に「ホスト名変更して、再起動して、○○設定して、再起動して、○○インストールして」みたいに何度か再起動が必要な構築を自動化する場合、OS起動時にスクリプトを自動実行する機能が必要になります。

GPOには機能を有効にする設定がありますが、ワークグループ環境や、ドメイン参加前の複数サーバーに対してGPO一括管理は出来ません。

でも、GPOはレジストリを更新しているので、どのレジストリを更新しているのかがわかれば GPO を使わなくても機能設定をすることが出来ます。

という事で、Let's Registry hack !!

# RunOnceEx でも出来そうだと見つけたのは hack した後なので調べていませんw

 

この GPO 設定で PowerShell を自動する際のレジストリ設定は以下になっていました。

 

「Key:Script」が起動する .ps1 、「Key:Parameters」 が引数です。(どちらも複数個所あり)

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0
Key: FileSysPath
Type: String
Value: C:\\Windows\\System32\\GroupPolicy\\Machine

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0
Key: PSScriptOrder
Type: DWord
Value: 3

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0
Key: Script
Type: String
Value: autoexec.ps1
RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0
Key: Parameters
Type: String
Value:
RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0
Key: IsPowershell
Type: DWord
Value: 1
RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

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

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0
Key: PSScriptOrder
Type: DWord
Value: 3
RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

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

Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0
Key: Parameters
Type: String
Value:
RegSet $RegPath $RegKey $RegKeyType $RegKeyValue

 

こいつをハンドリングする関数も作成しました。

EnableAutoexec に自動起動する .ps1 のフルパスと引数(省略可)を渡すと、自動起動スクリプトとして登録して(auroexec.ps1としてコピーして)再起動します。

RunOnceと違って、自動消去されないので DisableAutoexec で明示的にレジストリとスクリプトを消す必要があります。


##########################################################################
# レジストリ追加/更新
##########################################################################
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) ){
            echo "Add Registry : $RegPath"
            md $RegPath
        }
    }

    # Key有無確認
    Get-ItemProperty $RegPath -name $RegKey
    # キーがあった時
    if( $? ){
        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 ){
    ### 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

    $TergetPath = "C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup"
    $TergetFile = Join-Path $TergetPath "autoexec.ps1"

    if( -not (Test-Path $TergetPath)){
        md $TergetPath
    }

    copy $ScriptName $TergetFile -Force

    if( -not(Test-Path $TergetFile)){
        return
    }

    # 確実にフラッシュされるように少し待つ
    sleep 30
    Restart-Computer -Force
}

##########################################################################
# 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
    }
}

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.