LAPS運用のためのLocal Adminユーザーをスタートアップスクリプトで生成
Active Directory(AD)環境で、各PCのローカル管理者を管理する機能として「Local Administrator Password Solution(LAPS)」があり、この機能の使い方を説明しているサイトはたくさんあり、例えばこちらなど。
これらのサイトを見れば、設定自体は簡単にできるのですが、私が担当した環境の場合はもう1点問題がありました。 それは
「AD環境に移行する前はワークグループ環境で各利用者ごとにアカウントは異なっており、かつその各アカウントがローカルの管理者権限も持っていた」
ということ。
LAPSでは管理できる管理者権限は、Administrator、もしくはGPOで定義した共通のアカウント名のみ。
そこで、対処として、
- ローカル管理者権限をもった共通のアカウントを作成
- 個別のアカウントからは管理者権限を削除
を実施するスクリプトを作成し、このスクリプトをGPOのスタートアップスクリプトで実施するようにしてみました。
作成したスクリプトは下記
$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
に前述のスクリプトで作成するアカウント名を定義
以上になります。
