以前、Windows端末の大量展開を行った際、現地で一斉にプリンタドライバを設定し直す作業があり、
1台ずつプリンタを削除したり、あのインストーラやらを実行したりなんてできない!と思い、作成したバッチです。
プリンタのコントロール権限の部分もコマンドでできるよう作成しました。
目次
コマンドの内容
コマンドは以下の通りです。
こちらをバッチファイルにして使います。
REM 既存のプリンタの表示を削除
call rundll32 printui.dll,PrintUIEntry /dl /n "削除するプリンタ名" /q
REM 既存プリンタのドライバ自体をを削除
call rundll32 printui.dll,PrintUIEntry /dd /m "削除するプリンタのドライバ名" /q
REM 新規プリンタのポートを作成(必要なポートに応じてIPアドレスを入力)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prnport.vbs -a -s %computername% -r 192.168.1.XXX -h 192.168.1.XXX -o raw -n 9100
REM 新規プリンタのドライバインストール
REM(インストールの際には、ドライバのパッケージに入っているinfファイルの抽出が必要で、抽出したものをこのコマンド内で指定してあげる必要があります。)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prndrvr.vbs -a -m "追加するプリンタのドライバ名" -v 3 -i "追加するプリンタドライバのINFファイルの保管パス"
REM 新規プリンタデバイスの表示("表示名" "プリンタ名" "ポート作成済みのIPアドレス"の順番で入力します。)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prnmngr.vbs -a -s %computername% -p "追加するプリンタの表示名" -m "追加するプリンタのドライバ名" -r 192.168.1.XXX
REM ============================================================
REM 対象プリンタに対して「Everyone/フルコントロール」権限を付与するコマンド
REM ============================================================
@(echo '> NUL
echo off)
REM 管理者権限か確認
NET SESSION > NUL 2>&1
REM 管理者でなければ -ExecutionPolicy してから再起実行(RESTART)
IF %ERRORLEVEL% neq 0 goto RESTART
REM 管理者権限なら PS を呼んで★を実行する
setlocal enableextensions
set "THIS_PATH=%~f0"
set "PARAM_1=%~1"
PowerShell.exe -Command "iex -Command ((gc \"%THIS_PATH:`=``%\") -join \"`n\")"
exit /b %errorlevel%
:RESTART
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process %~f0 -Verb runas"
exit
') | sv -Name TempVar
# ここから先に PowerShellスクリプトを記述する(コメントもREMでなく「#」になるので注意)
# ============================================================
# PowerShellスクリプトを記述(ここからは1台のプリンタにつき、1セットずつ繰り返しコマンドが必要です。)
# 設定する際には、「$user」に対象ユーザー名と「$printerName」に対象のプリンタ名を指定してください。
# ============================================================
$user = "everyone" # 対象ユーザ名(基本的に権限追加するのは、Everyoneかと思います。)
$printerName = "対象プリンタの表示名" # 対象プリンタ名
$printer = Get-WmiObject -Class win32_printer |
Where-Object {$_.Name -eq $printerName}
# プリンタのSecurity Descriptorを取得する
$sd = $printer.GetSecurityDescriptor().Descriptor
# DACLから$user以外のACEを取得する
$aces = @($sd.DACL |
Where-Object {$_.Trustee.Name -ne $user})
# ACEオブジェクトを生成する関数
# see: https://docs.microsoft.com/ja-jp/windows/desktop/CIMWin32Prov/setsecuritydescriptor-method-in-class-win32-printer
function createAce
{
param([string]$user, [int]$accessMask, [int]$type, [int]$flags)
$ace = ([WMIClass] "Win32_Ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
$SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier])
[byte[]] $SIDArray = ,0 * $SID.BinaryLength
$SID.GetBinaryForm($SIDArray,0)
$Trustee.Name = $user
$Trustee.SID = $SIDArray
$ace.AccessMask = $accessMask
$ace.AceType = $type
$ace.AceFlags = $flags
$ace.Trustee = $Trustee
return $ace
}
# $user以外のACEと新しく作った$userのACEを結合
$aces +=
@(createAce -user $user -accessMask 983052 -type 0 -flags 0) + # ManagePrinters
@(createAce -user $user -accessMask 983088 -type 0 -flags 9) # ManageDocuments
$sd.DACL = [System.Management.ManagementBaseObject[]]$aces # DACLを更新
$printer.psbase.Scope.Options.EnablePrivileges = $true # 上書き許可
$ret = $printer.SetSecurityDescriptor($sd).ReturnValue # Security Descriptorを更新
if($ret -eq 0)
{
Write-Host "${user}の${printerName}に対するアクセス権を更新しました。"
}
else
{
Write-Host "アクセス権更新に失敗しました。"
}
# ============================================================
# 対象プリンタに対して「Everyone/フルコントロール」権限を付与するコマンド終了
# ============================================================
ちなみに、ここでいう「Everyone フルコントロール」とは、「プリンタのプロパティ」を開いた時の「セキュリティ」タブ内にあるアクセス許可のチェックを全て入れることです。
こちらの内容は単体で記事にもしてあります。
【Windows】「プリンターのプロパティ」のセキュリティアクセスをすべて許可する一括変更バッチを作成し…
バッチの内容 バッチの基本的な内容は以下の通りです。設定する場所は、以下の2箇所です。 「$user = “everyone” 」「$printerName = “対象プリンタの表示名” 」 「$pri…
これだけだと分かりづらい場合があるので、
次のセクションで、実際のプリンタ名に置き換えて作成してみました。
コマンドの使用例
実際に使うとなると、こんな感じです。
例として、
- 削除するプリンタは、「EPSON PX-S7050X」(表示名は、PX-S7050X)
- 追加するプリンタは、「EPSON LP-S3250(IPは 192.168.1.201)」(表示名は、LP-S3250)
(追加するプリンタの「INFファイル」を”C:\NULFAS\PR_DRV\LPS3250_x64_258JA\WINX64\E_WFBACJ.INF”に置いたとします。)
に置き換えてみます。
REM 既存のプリンタの表示を削除(別のプリンタの時は、"PX-S7050X"の部分を違うプリンタ名に変更)
call rundll32 printui.dll,PrintUIEntry /dl /n "PX-S7050X" /q
REM 既存プリンタのドライバ自体をを削除(別のプリンタの時は、"EPSON PX-S7050X"の部分を違うドライバ名に変更)
call rundll32 printui.dll,PrintUIEntry /dd /m "EPSON PX-S7050X" /q
REM 新規プリンタのポートを作成(必要なポートに応じてIPアドレスを入力)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prnport.vbs -a -s %computername% -r 192.168.1.201 -h 192.168.1.201 -o raw -n 9100
REM 新規プリンタのドライバインストール
REM(インストールの際には、ドライバのパッケージに入っているinfファイルの抽出が必要で、抽出したものをこのコマンド内で指定してあげる必要があります。)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prndrvr.vbs -a -m "EPSON LP-S3250" -v 3 -i "C:\NULFAS\PR_DRV\LPS3250_x64_258JA\WINX64\E_WFBACJ.INF"
REM 新規プリンタデバイスの表示("表示名" "プリンタ名" "ポート作成済みのIPアドレス"の順番で入力します。)
call cscript C:\Windows\System32\Printing_Admin_Scripts\ja-JP\prnmngr.vbs -a -s %computername% -p "LP-S3250" -m "EPSON LP-S3250" -r 192.168.1.201
REM ============================================================
REM 対象プリンタに対して「Everyone/フルコントロール」権限を付与するコマンド
REM ============================================================
@(echo '> NUL
echo off)
REM 管理者権限か確認
NET SESSION > NUL 2>&1
REM 管理者でなければ -ExecutionPolicy してから再起実行(RESTART)
IF %ERRORLEVEL% neq 0 goto RESTART
REM 管理者権限なら PS を呼んで★を実行する
setlocal enableextensions
set "THIS_PATH=%~f0"
set "PARAM_1=%~1"
PowerShell.exe -Command "iex -Command ((gc \"%THIS_PATH:`=``%\") -join \"`n\")"
exit /b %errorlevel%
:RESTART
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process %~f0 -Verb runas"
exit
') | sv -Name TempVar
# ここから先に PowerShellスクリプトを記述する(コメントもREMでなく「#」になるので注意)
# ============================================================
# PowerShellスクリプトを記述(ここからは1台のプリンタにつき、1セットずつ繰り返しコマンドが必要です。)
# 設定する際には、「$user」に対象ユーザー名と「$printerName」に対象のプリンタ名を指定してください。
# ============================================================
$user = "everyone"
$printerName = "LP-S3250"
$printer = Get-WmiObject -Class win32_printer |
Where-Object {$_.Name -eq $printerName}
# プリンタのSecurity Descriptorを取得する
$sd = $printer.GetSecurityDescriptor().Descriptor
# DACLから$user以外のACEを取得する
$aces = @($sd.DACL |
Where-Object {$_.Trustee.Name -ne $user})
# ACEオブジェクトを生成する関数
# see: https://docs.microsoft.com/ja-jp/windows/desktop/CIMWin32Prov/setsecuritydescriptor-method-in-class-win32-printer
function createAce
{
param([string]$user, [int]$accessMask, [int]$type, [int]$flags)
$ace = ([WMIClass] "Win32_Ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
$SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier])
[byte[]] $SIDArray = ,0 * $SID.BinaryLength
$SID.GetBinaryForm($SIDArray,0)
$Trustee.Name = $user
$Trustee.SID = $SIDArray
$ace.AccessMask = $accessMask
$ace.AceType = $type
$ace.AceFlags = $flags
$ace.Trustee = $Trustee
return $ace
}
# $user以外のACEと新しく作った$userのACEを結合
$aces +=
@(createAce -user $user -accessMask 983052 -type 0 -flags 0) + # ManagePrinters
@(createAce -user $user -accessMask 983088 -type 0 -flags 9) # ManageDocuments
$sd.DACL = [System.Management.ManagementBaseObject[]]$aces # DACLを更新
$printer.psbase.Scope.Options.EnablePrivileges = $true # 上書き許可
$ret = $printer.SetSecurityDescriptor($sd).ReturnValue # Security Descriptorを更新
if($ret -eq 0)
{
Write-Host "${user}の${printerName}に対するアクセス権を更新しました。"
}
else
{
Write-Host "アクセス権更新に失敗しました。"
}
# ============================================================
# 対象プリンタに対して「Everyone/フルコントロール」権限を付与するコマンド終了
# ============================================================