LAPS運用のためのLocal Adminユーザーをスタートアップスクリプトで生成

2020年7月29日

Active Directory(AD)環境で、各PCのローカル管理者を管理する機能として「Local Administrator Password Solution(LAPS)」があり、この機能の使い方を説明しているサイトはたくさんあり、例えばこちらなど。
これらのサイトを見れば、設定自体は簡単にできるのですが、私が担当した環境の場合はもう1点問題がありました。 それは
「AD環境に移行する前はワークグループ環境で各利用者ごとにアカウントは異なっており、かつその各アカウントがローカルの管理者権限も持っていた」
ということ。

LAPSでは管理できる管理者権限は、Administrator、もしくはGPOで定義した共通のアカウント名のみ。

そこで、対処として、

  • ローカル管理者権限をもった共通のアカウントを作成
  • 個別のアカウントからは管理者権限を削除

を実施するスクリプトを作成し、このスクリプトをGPOのスタートアップスクリプトで実施するようにしてみました。

作成したスクリプトは下記

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ErrorActionPreference="Stop"
function Log($Msg) {
# ログの出力先
$LogPath = "\\share\logs"
# ログファイル名
$LogFile = "add_admin_" + $env:COMPUTERNAME +"_" + $env:USERNAME + ".log"
# ログファイル名
$LogFileName = Join-Path $LogPath $LogFile
# ログ出力
Write-Output $Msg | Out-File -FilePath $LogFileName -Encoding Default -append
}
$Msg = @()
$TmpStatus = 0
#Local管理者のアカウント名を定義
Set-Variable -name LocalAdminName -value "LapsAdmin" -option constant
$AdminCount = Get-LocalUser | Where-Object -FilterScript { $_.Name -eq $LocalAdminName }
if ($AdminCount.length -eq 0){
$Msg += Write-Output "$(Get-Date -Format G) Local管理者を追加する処理を開始します。"
#ローカル管理者の初期パスワードを定義
$Password = ConvertTo-SecureString ($Env:COMPUTERNAME + "Admin#") -AsPlainText -Force
try{
New-LocalUser $LocalAdminName -Password $Password
}
catch {
$Msg += Write-Output ('Error message is ' + $_.Exception.Message)
$TmpStatus = 9
}
if ($TmpStatus -eq 0){
#Administratosに追加する
$Msg += Write-Output "$(Get-Date -Format G) Administratosに追加する処理を開始します。"
try{
Add-LocalGroupMember -Group "Administrators" -Member $LocalAdminName
}
catch {
$Msg += Write-Output ('Error message is ' + $_.Exception.Message)
$TmpStatus = 9
}
}
}
#AdministratorsのメンバーのうちLocalユーザーの情報を変数に格納する
$admin_member_list = (
Get-LocalGroupMember -Group "Administrators" |
Where-Object -FilterScript { ($_.PrincipalSource -eq "Local") `
-and ($_.ObjectClass -eq "ユーザー" ) `
-and ($_.Name -notlike "*$LocalAdminNam") `
-and ($_.Name -notlike "*Administrator")}
).Name
foreach ($admin_member in $admin_member_list) {
$Msg += Write-Output "$(Get-Date -Format G) Administratorsからメンバを削除する処理を開始します。"
try {
Remove-LocalGroupMember -Group "Administrators" -Member $admin_member
$Msg += Write-Output "$admin_member をAdministratorsから削除しました"
}
catch {
$Msg += Write-Output ('Error message is ' + $_.Exception.Message)
}
}
if ($Msg.length -gt 0){
Log($Msg)
}
$ErrorActionPreference="Stop" function Log($Msg) { # ログの出力先 $LogPath = "\\share\logs" # ログファイル名 $LogFile = "add_admin_" + $env:COMPUTERNAME +"_" + $env:USERNAME + ".log" # ログファイル名 $LogFileName = Join-Path $LogPath $LogFile # ログ出力 Write-Output $Msg | Out-File -FilePath $LogFileName -Encoding Default -append } $Msg = @() $TmpStatus = 0 #Local管理者のアカウント名を定義 Set-Variable -name LocalAdminName -value "LapsAdmin" -option constant $AdminCount = Get-LocalUser | Where-Object -FilterScript { $_.Name -eq $LocalAdminName } if ($AdminCount.length -eq 0){ $Msg += Write-Output "$(Get-Date -Format G) Local管理者を追加する処理を開始します。" #ローカル管理者の初期パスワードを定義 $Password = ConvertTo-SecureString ($Env:COMPUTERNAME + "Admin#") -AsPlainText -Force try{ New-LocalUser $LocalAdminName -Password $Password } catch { $Msg += Write-Output ('Error message is ' + $_.Exception.Message) $TmpStatus = 9 } if ($TmpStatus -eq 0){ #Administratosに追加する $Msg += Write-Output "$(Get-Date -Format G) Administratosに追加する処理を開始します。" try{ Add-LocalGroupMember -Group "Administrators" -Member $LocalAdminName } catch { $Msg += Write-Output ('Error message is ' + $_.Exception.Message) $TmpStatus = 9 } } } #AdministratorsのメンバーのうちLocalユーザーの情報を変数に格納する $admin_member_list = ( Get-LocalGroupMember -Group "Administrators" | Where-Object -FilterScript { ($_.PrincipalSource -eq "Local") ` -and ($_.ObjectClass -eq "ユーザー" ) ` -and ($_.Name -notlike "*$LocalAdminNam") ` -and ($_.Name -notlike "*Administrator")} ).Name foreach ($admin_member in $admin_member_list) { $Msg += Write-Output "$(Get-Date -Format G) Administratorsからメンバを削除する処理を開始します。" try { Remove-LocalGroupMember -Group "Administrators" -Member $admin_member $Msg += Write-Output "$admin_member をAdministratorsから削除しました" } catch { $Msg += Write-Output ('Error message is ' + $_.Exception.Message) } } if ($Msg.length -gt 0){ Log($Msg) }
$ErrorActionPreference="Stop"
function Log($Msg) {
 
    # ログの出力先
    $LogPath = "\\share\logs"
    # ログファイル名
    $LogFile = "add_admin_" +  $env:COMPUTERNAME +"_" + $env:USERNAME + ".log"
    # ログファイル名
    $LogFileName = Join-Path $LogPath $LogFile
    # ログ出力
    Write-Output $Msg | Out-File -FilePath $LogFileName -Encoding Default -append
 
}
$Msg = @()
$TmpStatus = 0

#Local管理者のアカウント名を定義
Set-Variable -name LocalAdminName -value "LapsAdmin" -option constant

$AdminCount = Get-LocalUser | Where-Object -FilterScript { $_.Name -eq $LocalAdminName }
if ($AdminCount.length -eq 0){
    $Msg += Write-Output "$(Get-Date -Format G) Local管理者を追加する処理を開始します。"
    #ローカル管理者の初期パスワードを定義
    $Password = ConvertTo-SecureString  ($Env:COMPUTERNAME + "Admin#") -AsPlainText -Force
    try{
        New-LocalUser $LocalAdminName -Password $Password
    }
    catch {
        $Msg += Write-Output ('Error message is ' + $_.Exception.Message)
        $TmpStatus = 9
    }

    if ($TmpStatus -eq 0){
        #Administratosに追加する
        $Msg += Write-Output "$(Get-Date -Format G) Administratosに追加する処理を開始します。"
        try{
            Add-LocalGroupMember -Group "Administrators" -Member $LocalAdminName
        }
        catch {
            $Msg += Write-Output ('Error message is ' + $_.Exception.Message)
            $TmpStatus = 9
        }
    }
}
#AdministratorsのメンバーのうちLocalユーザーの情報を変数に格納する
$admin_member_list = (
    Get-LocalGroupMember -Group "Administrators" |
    Where-Object -FilterScript { ($_.PrincipalSource -eq "Local") `
                             -and ($_.ObjectClass -eq "ユーザー" ) `
                             -and ($_.Name -notlike "*$LocalAdminNam") `
                             -and ($_.Name -notlike "*Administrator")}
    ).Name

foreach ($admin_member in $admin_member_list) {
    $Msg += Write-Output "$(Get-Date -Format G) Administratorsからメンバを削除する処理を開始します。"
    try {
        Remove-LocalGroupMember -Group "Administrators" -Member $admin_member
        $Msg += Write-Output "$admin_member をAdministratorsから削除しました"
    }
    catch {
        $Msg += Write-Output ('Error message is ' + $_.Exception.Message)
    }
}
if ($Msg.length -gt 0){
   Log($Msg)
}

また、追加でGPOに設定した内容は

  • コンピューターの構成>ポリシー>Windowsの設定
    スクリプト(スタートアップ/シャットダウン)
    のスタートアップスクリプトに前述のスクリプトを
  • コンピューターの構成>ポリシー>管理用テンプレート>LAPS
    Name of administrator account to mannage
    に前述のスクリプトで作成するアカウント名を定義

以上になります。