【Windows】プリンタの削除からインストールまでを全自動バッチで設定して実行してみた!(コマンドプロンプト・設定例あり!)

以前、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 フルコントロール」とは、「プリンタのプロパティ」を開いた時の「セキュリティ」タブ内にあるアクセス許可のチェックを全て入れることです。

こちらの内容は単体で記事にもしてあります。

これだけだと分かりづらい場合があるので、
次のセクションで、実際のプリンタ名に置き換えて作成してみました。

コマンドの使用例

実際に使うとなると、こんな感じです。
例として、

  • 削除するプリンタは、「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/フルコントロール」権限を付与するコマンド終了
# ============================================================
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次