PowerShellでユーザーごとに既定プリンターを切り替える方法|動くスクリプトと失敗時の対処

PowerShellでユーザーごとに既定プリンターを切り替えるなら、結論はシンプルです。Set-Printer ではなく Win32_Printer の SetDefaultPrinter() を、切り替えたい本人のユーザーセッションで実行します。既定プリンターはユーザー単位で保持され、メソッドも呼び出したユーザーの既定プリンターを変更する仕様だからです。管理者や SYSTEM で実行したのに、狙った人の設定だけ変わらないのはこの仕組みが原因です。(Microsoft Learn)

実務で大事なのは、単にコマンドを覚えることではありません。対象プリンターがそのユーザーに見えているか、Windows の既定プリンター自動管理が邪魔していないか、RDS や AVD のセッションで別設定に戻されないかまで見て、はじめて安定して運用できます。ここでは、動く PowerShell 例、設定場所、失敗しやすいポイント、戻し方、代替策までまとめます。

目次

まず押さえる結論

Set-Printer は既存プリンターの構成変更用で、構文を見ても既定化専用のパラメーターはありません。PowerShell で既定プリンターを切り替えたいなら、WMI/CIM の Win32_Printer.SetDefaultPrinter() を使うほうが迷いません。(Microsoft Learn)

この仕様から逆算すると、やることは次の順番になります。

  1. 切り替えたい本人のユーザー文脈で実行する
  2. そのユーザーに見えているプリンター名を確認する
  3. SetDefaultPrinter() で既定化する
  4. Windows の自動管理や RDS/AVD の上書き要因を止める

この順番を守るだけで、かなりの失敗を避けられます。

設定場所と前提条件

既定プリンターの情報は HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows 配下にあり、既定プリンター名は Device に保存されます。Windows の既定プリンター自動管理に関わる LegacyDefaultPrinterMode も同じキー系統です。つまり、既定プリンターは PC 共通設定ではなく、ユーザー設定として扱う前提で設計したほうが噛み合います。(Microsoft Learn)

Windows 側の自動管理が有効だと、PowerShell で切り替えても別タイミングで上書きされることがあります。ドメイン運用なら、ユーザー設定の Turn off Windows default printer management を GPO や MDM でそろえておくと安定しやすくなります。(Microsoft Learn)

RDS や Azure Virtual Desktop では、クライアント側の既定プリンターをセッション側の既定プリンターに自動反映する挙動が入ることがあります。ログオン時には正しく切り替わるのに、再接続すると元に戻るなら、Do not set default client printer to be default printer in a session などのプリンター リダイレクト設定も確認してください。(Microsoft Learn)

単体で確実に切り替える PowerShell

まずは 1 ユーザー・1 台で確実に動く状態を作るのが近道です。Win32_Printer には Default プロパティがあるので、一覧確認と切り替え確認を同じ系統のコマンドで完結できます。(Microsoft Learn)

function Set-UserDefaultPrinter {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$PrinterName
    )

    $allPrinters = Get-CimInstance -ClassName Win32_Printer

    $currentDefault = $allPrinters |
        Where-Object Default |
        Select-Object -ExpandProperty Name -First 1

    $targetPrinter = $allPrinters |
        Where-Object Name -eq $PrinterName |
        Select-Object -First 1

    if (-not $targetPrinter) {
        throw "プリンター '$PrinterName' が現在のユーザーに見つかりません。まず一覧を確認してください。"
    }

    $result = Invoke-CimMethod -InputObject $targetPrinter -MethodName SetDefaultPrinter

    if ($result.ReturnValue -ne 0) {
        throw "既定プリンターの変更に失敗しました。ReturnValue=$($result.ReturnValue)"
    }

    $newDefault = Get-CimInstance -ClassName Win32_Printer |
        Where-Object Default |
        Select-Object -ExpandProperty Name -First 1

    [pscustomobject]@{
        Before = $currentDefault
        After  = $newDefault
    }
}

# まずは名前を確認
Get-CimInstance -ClassName Win32_Printer |
    Select-Object Name, Default

# 実行例
Set-UserDefaultPrinter -PrinterName '経理室-LBP'

ここで重要なのは、$PrinterName に入れる値をそのユーザーから見えている表示名そのままにすることです。共有プリンターは、サーバー上の共有名と Windows 上の表示名がずれることがあります。先に一覧を出して、表示された名前をそのままコピペするほうが確実です。

SetDefaultPrinter() は成功時に 0 を返します。スクリプトで ReturnValue を見ておくと、切り替わらない原因が「名前ミスなのか」「実行文脈なのか」を切り分けやすくなります。(Microsoft Learn)

ユーザーごとに切り替えるログオンスクリプト例

共有 PC や RDS で「ログオンした人ごとに既定プリンターを変えたい」なら、上の関数をユーザーログオン時に呼び出します。SetDefaultPrinter() は呼び出したユーザーに対して動くので、コンピューター起動時ではなく、ユーザーログオン時に動かす設計が基本です。Microsoft の KB でも、初回ログオン時の既定化失敗に対する回避策として、ログオン後のスケジュールタスクを挙げています。(Microsoft Learn)

function Set-UserDefaultPrinter {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$PrinterName
    )

    $allPrinters = Get-CimInstance -ClassName Win32_Printer
    $targetPrinter = $allPrinters | Where-Object Name -eq $PrinterName | Select-Object -First 1

    if (-not $targetPrinter) {
        throw "プリンター '$PrinterName' が現在のユーザーに見つかりません。"
    }

    $result = Invoke-CimMethod -InputObject $targetPrinter -MethodName SetDefaultPrinter

    if ($result.ReturnValue -ne 0) {
        throw "既定プリンターの変更に失敗しました。ReturnValue=$($result.ReturnValue)"
    }
}

$userPrinterMap = @{
    'CONTOSO\tanaka' = '経理室-LBP'
    'CONTOSO\suzuki' = '営業部-Color'
    'CONTOSO\yamada' = '出荷ラベル'
}

$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

if (-not $userPrinterMap.ContainsKey($currentUser)) {
    Write-Warning "割り当てがありません: $currentUser"
    return
}

Set-UserDefaultPrinter -PrinterName $userPrinterMap[$currentUser]

この形なら、ユーザーごとに既定プリンターを切り替えるログオンスクリプトとしてそのまま流用できます。人数が増えてきたら、ハッシュテーブルを CSV や JSON に切り出すと、部署異動やプリンター更改にも追従しやすくなります。

対象プリンターがまだ入っていない場合の追加方法

対象プリンターがそのユーザーに見えていないなら、先に接続を作ります。PowerShell では Add-Printer -ConnectionName でネットワーク プリンター接続を追加できます。ただし環境によっては、ドライバーや権限の都合で管理者資格情報が必要になることがあります。(Microsoft Learn)

Add-Printer -ConnectionName '\\PRINT01\Accounting-LBP'

PowerShell だけにこだわらないなら、Windows 標準の PrintUIEntry も使えます。/in はコマンドを実行したユーザー向けの接続、/ga はその PC の全ユーザー向けの接続で、反映は次回ログオン時です。共有 PC では、接続は PC 単位で配り、既定プリンターだけをユーザー単位で決めると運用しやすくなります。(Microsoft Learn)

# 実行したユーザーだけに接続を追加
rundll32 printui.dll,PrintUIEntry /in /n\\PRINT01\Accounting-LBP

# そのPCの全ユーザー向けに接続を追加
# 反映は次回ログオン時
rundll32 printui.dll,PrintUIEntry /ga /n\\PRINT01\Accounting-LBP

PrintUIEntry は、ドキュメントどおりの表記で実行するのが安全です。(Microsoft Learn)

初回ログオンの同じ処理の中で「プリンター接続を作る」「その場で既定化する」まで一気にやると、Spooler がまだ接続情報を作り終えておらず失敗する既知事象があります。GPO で配る場合は、追加と既定化を同じフェーズに詰め込まず、ログオン後タスクで既定化するほうが安定します。(Microsoft Learn)

失敗しやすいポイントと対処

PowerShell で既定プリンターを切り替えるときに、特に詰まりやすいのは次のパターンです。

症状ありがちな原因まずやること
スクリプトは完了したのに、その人の既定プリンターが変わらない管理者・SYSTEM・別資格情報で実行している対象ユーザーのログオンセッションで実行する
一度は変わるが、あとで別のプリンターに戻るWindows の自動管理、RDS/AVD のリダイレクトが上書きしている自動管理を止め、RDS/AVD の既定プリンター関連ポリシーを確認する
プリンターが見つかりません になる表示名の指定ミス、または接続未作成一覧を再取得し、表示名をそのまま使う
初回ログオンだけ失敗するGPO/GPP と Spooler のタイミング競合ログオン後タスクに分離する
追加だけ成功して既定化だけ失敗する接続直後でまだユーザーセッションに反映されていない再ログオン、再試行、または 2 段階運用にする

この表に当てはまるかを先に見るだけでも、無駄なデバッグがかなり減ります。

戻し方

戻し方は単純です。切り替え前の既定プリンター名を控えておき、その名前に対してもう一度 SetDefaultPrinter() を実行すれば元に戻せます。テスト時は、変更前の名前を変数やファイルに保存してから実行すると安心です。(Microsoft Learn)

$beforePrinter = '元の既定プリンター名'
Set-UserDefaultPrinter -PrinterName $beforePrinter

追加したプリンター接続自体が不要なら、Remove-Printer で削除できます。名前でもオブジェクトでも指定できます。(Microsoft Learn)

Remove-Printer -Name '経理室-LBP'

PowerShell以外の代替策

PowerShell が最適なのは、ユーザー名や条件で柔軟に分岐したいときです。逆に、既存のバッチ資産を活かしたい、運用がレガシー寄り、という環境では prnmngr も十分実用的です。-t で既定プリンターを指定できます。(Microsoft Learn)

cscript "$env:WINDIR\System32\Printing_Admin_Scripts\<language>\prnmngr.vbs" -t -p "経理室-LBP"

また、多人数運用では「接続の配布」と「既定化」を分けたほうが安定します。接続は GPO や PrintUIEntry /ga で PC 単位に配り、既定化だけを PowerShell のログオンスクリプトやログオン後タスクで行う形です。初回ログオンで GPP が既定プリンター設定に失敗しやすい既知事象も、この分離で避けやすくなります。(Microsoft Learn)

まとめ

PowerShellでユーザーごとに既定プリンターを切り替えるコツは、Set-Printer ではなく Win32_Printer.SetDefaultPrinter() を使い、対象ユーザーのログオン時に実行することです。あわせて、Windows の既定プリンター自動管理と、RDS/AVD の既定プリンター上書き設定を止めておくと、切り替えが安定します。(Microsoft Learn)

最初の一歩としては、まず Get-CimInstance Win32_Printer | Select-Object Name, Default で表示名を確認し、単体の切り替えを 1 ユーザーで成功させることです。そこで問題がなければ、次にログオンスクリプト化し、最後にユーザーごとの分岐を足していく流れが失敗しにくい進め方です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次