|||||||||||||||||||||

なんぶ電子

- 更新: 

Power Shellでプリンタをインストール

Power Shell Printer Control

前回WindowsのPower Shellの基本的な設定と、ファイアウォールの変更してみました。今回はファイアウォール同様に利用しているPCが多くなると設定の手間が増えるプリンタの管理を、Power Shellのスクリプト化したいと思います。

Microsoft 「Docs Windows でのプリンターの操作」を参考にPowerShellでプリンタを操作してみます。

環境はWindows10です。PowerShellのバージョンは5.1でしたが、これを機に執筆時点のLTSの最新版である7.2にアップデートしました。

Power Shellのバージョン確認とアップデート

まずPowerShellのバージョンを確認します。バージョンは$PSVersionTableという変数に含まれているので読み出します。

PS C:¥> $PSVersionTable

Name         Value
----         -----
PSVersion    5.1.19041.1682
PSEdition    Desktop
..

アップデートファイルはGitHubに存在しますので、環境にあったものをダウンロードします。

今回は長く運用したいのでLTSがついた最新の64bit(x64)、Windowsインストーラー.msiをダウンロードしました。(7.2.6)

msi版でインストールするとデフォルトではc:¥Program Files¥PowerShell¥7¥pwsh.exeにインストールされます。

Windows10にバンドルされているものはsystem32¥WindowsPowerShell¥v1.0¥powershell.exeにあり、複数のバージョンが同居した状態となります。

旧バージョンを立ち上げる場合はpowershell、新バージョンはpwshと打ち込むことで環境を切り替えられるようです。

PS C:¥> powershell
Windows PowerShell
# これ以降はプリインストール版のシェルで実行されます
...
PS C:¥> pwsh
PowerShell 7.3.4
# これ以降は新たにインストールしたシェルで実行されます
...

基本的なコントロール

インストールされているプリンタの一覧を確認するには次のようにします。

PS> Get-CimInstance -Class Win32_Printer

WScript.NetworkというCOMオブジェクトからも表示させることができます。

(New-Object -ComObject WScript.Network).EnumPrinterConnections()

さらに、WScript.Networkを使えば、ネットワーク上の共有プリンタを追加することもできます。

(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("¥¥サーバー名¥プリンタ名")

通常使うプリンタの設定はWMI経由で行うことができます。

指定するプリンタオブジェクトをプリンタ一覧を表示したのと同じコマンドを使って変数に取得した後、そのプリンタ変数を引数にコマンドを実行しています。

$printer = Get-CimInstance -Class Win32_Printer -Filter "Name='プリンタ名'"
Invoke-CimMethod -InputObject $printer -MethodName SetDefaultPrinter

また通常使うプリンタの指定はWScript.Networkからも行えます。

(New-Object -ComObject WScript.Network).SetDefaultPrinter('プリンタ名')

ネットワーク上の共有プリンター接続を削除するには次のようにします。

(New-Object -ComObject WScript.Network).RemovePrinterConnection("¥¥サーバー名¥プリンタ名")

プリンタドライバのインストール

今度はQuiita:「Powershellでプリンターをインストール(概要)」を参考に、プリンタのインストールやポートの設定をしてみたいと思います。

Windowsでは、ドライバとポートの組み合わせがひとつのプリンタオブジェクトとして保存されています。プリンタドライバーのインストーラーを利用するとこれらを一度に行うことがおおいですが、PowerShellで管理する場合はそれぞれ別で設定します。

まずは利用するドライバをダウンロードしてきます。自己解凍形式(インストーラー)になっているものは7Zipなどのアーカイバ―を使って展開します。

その中にINFファイルがあるので、パスを覚えておきます。

INF内にWindowsのバージョンやアーキテクチャ別にドライバ名が記述されているので、名前を覚えておきます。ドライバ名の箇所が「%変数名%」となっていたら、同じファイル内で変数定義している場所からドライバ名を取得します。

INFファイルはアーキテクチャ別に分かれていたり、プリンタとFAXやスキャナで別々のものが用意されていたりすることもありますので注意して選択してください。

;コメント等で対象のアーキテクチャ等が照会されていると思います。
[セクション]
ドライバ名=....
%変数名%=...
...
;変数定義
[Strings]
%変数名%=ドライバ名
...

プリンタドライバのインストールはManagementClassから、行います。

これは.NETのAPIになるので、.NETが存在しないようならダウンロードしてインストールします。

WMIはCIMクラスのインスタンスの変更を監視してPCの変更指示に変換します。

ドライバの管理ではそのようなクラスであるWin32_PrinterDriverクラスを用います。

ポートの設定

ポートは「Win32_TcpIpPrinterPort」クラスを指定して操作します。

近年のWindowsでは9100番ポートを使った通信(Standard TCP/IP Portを使った通信)で、プリンタデータを送る事が多いです。これはRawという表記になっています。

従来からのネットワークプリンタ用のプロトコルLPR(LPD)を利用する場合は、ポート番号はは515(TCP)となります。

USBプリンタの場合は接続するとUSB001やUSB002といった仮想のプリンタポートが自動生成されますので、ポートの設定は不要です。

プリンタの登録

ドライバを追加してポートを作成しただけでは「プリンタとスキャナー」の画面の一覧には出てきません。そこでWin32_Printerクラスを用いてプリンタを生成します。

コーディング

次のコードに必要事項をいれ、管理者権限で実行するとプリンタドライバをインストールしポートを設定した上でOS上にプリンタを登録します。

install-printer.ps

# ----------    設定     ---------------
# ドライバのパス 通常はinfファイルがあるフォルダ
$DriverPath="ドライバフォルダへのパス"
# infファイルへのパス
$InfPath = "INFファイルへのフルパス.inf"
# ドライバ名
$DriverName="ドライバ名"
# IPアドレス
$IpAddress="IPアドレス"
# プリンタ名(任意)
$PrinterName="プリンタ名"
# プロトコル 1=raw 2=lpr
$Protocol = 1
# ポート 通常rawの場合9100 lprの場合は515
$PortNo = 9100
# ----------------------------------------------

# ---  プリンタドライバインストール ----
$PrinterDriverClass=New-Object System.Management.ManagementClass("Win32_PrinterDriver")

$NewPrinterDriver=$PrinterDriverClass.CreateInstance()

$NewPrinterDriver.Name=$DriverName

$NewPrinterDriver.Version=3

$NewPrinterDriver.DriverPath=$DriverPath

$NewPrinterDriver.InfName=$InfPath

$PrinterDriverClass.AddPrinterDriver($NewPrinterDriver)

$PrinterDriverClass.Put()

# --- ポート設定 ---
# USBの場合は不要
$PrinterPortClass=New-Object System.Management.ManagementClass("Win32_TcpIpPrinterPort")

$NewPort=$PrinterPortClass.CreateInstance()

$NewPort.name=$IpAddress

$NewPort.Protocol=$Protocol

$NewPort.HostAddress=$IpAddress

$NewPort.PortNumber=$PortNo

$NewPort.SnmpEnabled=$true

$NewPort.Put()

# --- プリンタの生成 ---
$PrinterClass=New-Object System.Management.ManagementClass("Win32_Printer")

$NewPrinter=$PrinterClass.CreateInstance()

$NewPrinter.drivername=$DriverName

# USBプリンタの場合はポート名を後述のようにします
$NewPrinter.PortName=$IpAddress

$NewPrinter.DeviceID=$PrinterName

$NewPrinter.Put()

# 通常使うプリンタに
# $NewPrinter.SetDefaultPrinter()

USBプリンタを設定する場合は、USBの後の連番がいくつになるかが不定なのでスクリプトを組みづらいですが、Get-PrinterPortコマンドから、Descriptionの値を頼りにポート名を見つける方法が考えられます。そこで得られたポート名をPortNameプロパティにセットします。

PS > Get-PrinterPort | Where Name -match "USB"

Name      ComputerName   Description         PortMonitor
----      ------------   -----------         -----------
USB002                   CanonG7000 series   Dynamic Print Mon...

# CanonG7000 seriesという値を決め打ちでポートを取得
$ports = Get-PrinterPort | Where-Object { $_.Name -Like "USB*" -and $_.Description -eq "CanonG7000 series" }

...
# プリンタを設定する時にポートを次のようにします
# $portsはnullになることがあるので注意してください
$printer.PortName=$ports[0].Name

参考にさせていただきましたサイトの皆様、ありがとうございました。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告