しばたテックブログ

気分で書いている技術ブログです。

gpeditを使わずにログオン・ログオフスクリプトを無理やり設定する

要はログオン・ログオフスクリプトをNon-GUIで設定したかったんです。
無理やりな方法なので余程の事がない限りやらない方が吉。

ログオン・ログオフスクリプトの実体

最初に、

www.atmarkit.co.jp

を見て頂ければわかるのですが、ログオン・ログオフスクリプトを含めたグループポリシーの実体はC:\Windows\System32\GroupPolicyフォルダ配下にある各種ファイルになります。

その中でもログオン・ログオフスクリプトを動作させるためには以下の構成が必要になります。

C:\
  Windows\
    System32\
      GroupPolicy\
        gpt.ini → グループポリシー全体の設定ファイル
        User\
          Scripts\
            scripts.ini   → ログオンスクリプトの設定ファイル
            psscripts.ini → PowerShellスクリプトの設定ファイル
            Logon\
              [ログオンスクリプト] → スクリプトファイル
            Logoff\
              [ログオフスクリプト] → スクリプトファイル

C:\Windows\System32\GroupPolicyフォルダは一度でもグループポリシーが設定されていれば各種ファイルが設定されていますし、何もしていなければ空フォルダとなっています。

で、上記のファイル・フォルダ構成を手動で"適切に"構成してやればgpeditを使わなくてもログオン・ログオフスクリプトを動作させることができます。

フォルダ構成を設定する

これはただフォルダを作るだけなので楽です。 PowerShellだとこんな感じでできます。

$GPRoot = "C:\Windows\System32\GroupPolicy"
New-Item (Join-Path $GPRoot "User\Scripts\Logon")  -ItemType Directory
New-Item (Join-Path $GPRoot "User\Scripts\Logoff") -ItemType Directory

gpt.iniを設定する

ここが一番厄介な部分になります。

C:\Windows\System32\GroupPolicyフォルダに何もない状態であれば以下の内容でgpt.iniファイルを作ってやればOKです。

[General]
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]
Version=65536

PowerShellだとこんな感じで作れます。

$GPRoot = "C:\Windows\System32\GroupPolicy"
@"
[General]
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]
Version=65536
"@ -replace "`n","`r`n" | Out-File -FilePath (Join-Path $GPRoot "gpt.ini") -Encoding ascii

で、このgpt.iniの中身について説明すると、上記のリンクにもありますが、gPCUserExtensionNamesユーザーの構成のCSEのリストになり*1{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}の部分がログオン・ログオフスクリプトを使うことを表しています。
また、Versionにはgpt.iniファイル自体のバージョン番号が記載され、上位4桁がユーザーの構成、下位4桁がコンピューターの構成なため、ユーザーの構成しか使わない上記の例では0x00010000 = 65536に設定する必要があります。

当然のことですが既存のグループポリシーが設定されている環境ではgpt.iniの内容は環境に応じて変わっていますのでファイルの整合性を損なわない様に上記の設定を追加してやる必要があります。

scripts.iniを設定する

scripts.iniにはログオン・ログオフスクリプトの情報を記載します。
ファイル自体は隠しファイルですが、隠しファイルにしなくてもスクリプトは動作します。

以下の様な感じの内容に設定する必要があります。

[Logon]
0CmdLine=Script1.bat
0Parameters=Param1

[Logoff]
0CmdLine=Script2.bat
0Parameters=Param2

[Logon][Logoff]セクションがそれぞれログオン・ログオフスクリプトを表しており、nCmdLine(n=0,1,2...)にスクリプトファイル名を、nParameters(n=0,1,2...)にスクリプトに渡す引数を指定してやります。

PowerShellだと以下の様な感じでファイルを生成することができます。

$GPRoot = "C:\Windows\System32\GroupPolicy"
@"
[Logon]
0CmdLine=Script1.bat
0Parameters=Param1

[Logoff]
0CmdLine=Script2.bat
0Parameters=Param2
"@ -replace "`n","`r`n" | Out-File -FilePath (Join-Path $GPRoot "User\Scripts\scripts.ini") -Encoding ascii
(Get-ItemProperty (Join-Path $GPRoot "User\Scripts\scripts.ini")).Attributes = "hidden"

scripts.iniファイルを設定して、C:\Windows\System32\GroupPolicy\User\Scripts\LogonおよびC:\Windows\System32\GroupPolicy\User\Scripts\Logoffフォルダにスクリプトファイルを展開してやればスクリプトが動作します。

psscripts.iniを設定する

psscripts.iniにはPowerShellのログオン・ログオフスクリプトの情報を記載します。
こちらも隠しファイルですが、隠しファイルにしなくてもスクリプトは動作します。

設定内容は以下の様な感じにします。

[ScriptsConfig]
StartExecutePSFirst=true
EndExecutePSFirst=false

[Logon]
0CmdLine=Script1.ps1
0Parameters=Param1

[Logoff]
0CmdLine=Script2.ps1
0Parameters=Param2

[ScriptsConfig]セクションのStartExecutePSFirstおよびEndExecutePSFirstにログオン・ログオフPowerShellスクリプトを最初に実行するか否かを記載します。
True最初に実行するで、False最後に実行するになります。未構成の場合はキー自体を削除してください。

nCmdLine(n=0,1,2...)nParameters(n=0,1,2...)についてはscripts.iniファイルと同様です。

また、ファイルの生成方法はこんな感じです。

$GPRoot = "C:\Windows\System32\GroupPolicy"
@"
[ScriptsConfig]
StartExecutePSFirst=true
EndExecutePSFirst=false

[Logon]
0CmdLine=Script1.ps1
0Parameters=Param1

[Logoff]
0CmdLine=Script2.ps1
0Parameters=Param2
"@ -replace "`n","`r`n" | Out-File -FilePath (Join-Path $GPRoot "User\Scripts\psscripts.ini") -Encoding ascii
(Get-ItemProperty (Join-Path $GPRoot "User\Scripts\psscripts.ini")).Attributes = "hidden"

最後に

とりあえずこんな感じでgpeditを使わずにログオン・ログオフスクリプトの設定をすることができます。
gpt.iniを手動で改変することになるので、Active Directory環境ではこの方法は絶対にやらない方が良いと思います。(そもそもGPMCから設定できるのでこれをやる必要がないですが...)

ワークグループ環境で複数台の端末に手早く設定をしたい場合や無人セットアップが必要な時にこの方法が使えるかもしれません。
何らかの設定ツールがあればうれしいのですが知っている方がいれば是非教えてください。

*1:ログオン・ログオンスクリプトはユーザーの構成の一要素になります