Windows の操作を自動化したい。 PowerShellに触れるのにもっとも簡単な題材はこれではないでしょうか。
そういえば、 プリンターに関する操作について触る機会がなくて紹介していませんでしたが、少し触ってみたので簡単に。
目次
Printer に関するコマンドレット(Cmdlet)
PowerShell 3.0 から以下のコマンドレットが利用可能になっています。
一連のコマンドレットは、PrintManagementモジュールに格納されているので見てみましょう。
Get-Command -Module PrintManagement
CommandType Name ModuleName ----------- ---- ---------- Function Add-Printer PrintManagement Function Add-PrinterDriver PrintManagement Function Add-PrinterPort PrintManagement Function Get-PrintConfiguration PrintManagement Function Get-Printer PrintManagement Function Get-PrinterDriver PrintManagement Function Get-PrinterPort PrintManagement Function Get-PrinterProperty PrintManagement Function Get-PrintJob PrintManagement Function Read-PrinterNfcTag PrintManagement Function Remove-Printer PrintManagement Function Remove-PrinterDriver PrintManagement Function Remove-PrinterPort PrintManagement Function Remove-PrintJob PrintManagement Function Rename-Printer PrintManagement Function Restart-PrintJob PrintManagement Function Resume-PrintJob PrintManagement Function Set-PrintConfiguration PrintManagement Function Set-Printer PrintManagement Function Set-PrinterProperty PrintManagement Function Suspend-PrintJob PrintManagement Function Write-PrinterNfcTag PrintManagement
多くのコマンドレットがありますね。
今回利用するのは、*-PrinterPort
コマンドレットです。
Get-Command -Module PrintManagement -Noun PrinterPort
CommandType Name ModuleName ----------- ---- ---------- Function Add-PrinterPort PrintManagement Function Get-PrinterPort PrintManagement Function Remove-PrinterPort PrintManagement
現在のプリンターポートを取得する
まずは、現在のプリンターポート取得です。
これは、Get-PrinterPort
コマンドレットで可能です。
Windows 8.1 インストール直後のデフォルトはこんな感じですね。
Get-PrinterPort
Name ComputerName Description PortMonitor ---- ------------ ----------- ----------- LPT1: Local Port Local Monitor COM3: Local Port Local Monitor LPT2: Local Port Local Monitor COM4: Local Port Local Monitor LPT3: Local Port Local Monitor PORTPROMPT: Local Port Local Monitor FILE: Local Port Local Monitor COM1: Local Port Local Monitor COM2: Local Port Local Monitor nul: Local Port Local Monitor SHRFAX: Fax Monitor Port Microsoft Shared Fax Monitor
プリンターポートの追加
TCP/IPプリンターポートを追加しましょう。
これは、Add-PrinterPort
コマンドレットで可能です。例えば、192.168.11.200 のプリンターポートを追加してみましょう。
TCP/IPプリンターポートは、通常ポートと名称を同一で作るのでこのままですね。(WindowsでGUIを使って追加したときのデフォルトの動作)
[ipaddress]$TCPIPPort = "192.168.11.200" Add-PrinterPort -PrinterHostAddress $TCPIPport -Name $TCPIPport
これで、Get-PrinterPort
すると追加結果がわかります。
Name ComputerName Description PortMonitor ---- ------------ ----------- ----------- COM1: Local Port Local Monitor COM2: Local Port Local Monitor COM3: Local Port Local Monitor COM4: Local Port Local Monitor FILE: Local Port Local Monitor LPT1: Local Port Local Monitor LPT2: Local Port Local Monitor LPT3: Local Port Local Monitor nul: Local Port Local Monitor PORTPROMPT: Local Port Local Monitor 192.168.11.200 Standard TCP/IP Port TCPMON.DLL SHRFAX: Fax Monitor Port Microsoft Shared Fax Monitor
プリンターポートの削除
誤って追加した場合は、Remove-PrinterPort
コマンドレットで削除可能です。
[ipaddress]$TCPIPPort = "192.168.11.200" Remove-PrinterPort -Name $TCPIPPort
消えてますね。
Name ComputerName Description PortMonitor ---- ------------ ----------- ----------- LPT1: Local Port Local Monitor COM3: Local Port Local Monitor LPT2: Local Port Local Monitor COM4: Local Port Local Monitor LPT3: Local Port Local Monitor PORTPROMPT: Local Port Local Monitor FILE: Local Port Local Monitor COM1: Local Port Local Monitor COM2: Local Port Local Monitor nul: Local Port Local Monitor SHRFAX: Fax Monitor Port Microsoft Shared Fax Monitor
既存プリンターへのポートセット
ないのですね。既定では。これは CIM (WMI) を利用します。
プリンターの取得
まずは Win43_printer
でプリンターを取得します。
$printer = Get-CimInstance -Class Win32_printer | where name -eq $printerName
PortName のセット
あとは、PortNameをセットします。単純にいうとこうですね。
$printer.PortName = $TCPIPport
ファンクション
面倒なので用意しました。
これはSet-PrinterPort のみの機能です。
#Requires -Version 3.0 function Set-PrinterPort { <# .Synopsis Set TCP/IP to PrinterName you specified. .DESCRIPTION This Cmdlet will Assign current TCP/IP Port include what you specified. .EXAMPLE Set-PrinterPort -TCPIPport 192.168.1.2 -printerName "HP-hogehoge" .EXAMPLE Set-PrinterPort -TCPIPport 192.168.1.2 -printerName "HP-hogehoge" -Verbose #> [CmdletBinding()] Param ( # Input TCP/IP port number you want to create, assign to Printer [Parameter( Mandatory, Position = 0)] [ipaddress] $TCPIPport, # Input Printer Name to asshign Port Number you want [Parameter( Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $printerName ) process { if (-not(Get-PrinterPort | where Name -eq $TCPIPport)) { throw ("Printer Port '{0}' not found exception!" -f $TCPIPport) } else { Write-Verbose ("Printer port '{0}' found." -f $TCPIPport) } $printers = Get-CimInstance -Class Win32_printer | where name -eq $printerName if ($printers.count -ne 0) { foreach ($printer in $printers) { if ($printer.PortName -ne $TCPIPport) { Write-Verbose ("Setting Printer '{0}' port from '{1}' to '{2}'" -f $printer.Name, $printer.PortName, $TCPIPport) $printer.PortName = $TCPIPport } else { Write-Verbose ("Printer '{0}' port '{1}' was already '{2}'" -f $printer.Name, $printer.PortName, $TCPIPport) } } } else { throw ("Printer name '{0}' not exist exception!" -f $printerName) } } }
こっちは、プリンターポートの有無を確認しなければ追加、さらに指定したプリンター名にセットまで拡張したものです。
#Requires -Version 3.0 function Set-PrinterPortExtend { <# .Synopsis Add/check TCP/IP and assign to PrinterName you specified. .DESCRIPTION This Cmdlet will check current TCP/IP Port include what you specified. If not exist, then add TCP/IP Port. Next, Get Printer Name as you desired and check Port Number which assigned to it. If PortNumber assigned was not same as Port Number you specified, then change it. .EXAMPLE Set-PrinterPort -TCPIPport 192.168.1.2 -printerName "HP*" .EXAMPLE Set-PrinterPort -TCPIPport 192.168.1.2 -printerName "HP*" -Verbose #> [CmdletBinding()] Param ( # Input TCP/IP port number you want to create, assign to Printer [Parameter( Mandatory, Position = 0)] [ipaddress] $TCPIPport, # Input Printer Name to asshign Port Number you want [Parameter( Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $printerName ) process { if (-not(Get-PrinterPort | where Name -eq $TCPIPport)) { if ($includeAddPort) { Write-Warning ("Printer port '{0}' not found. Adding port." -f $TCPIPport) Add-PrinterPort -PrinterHostAddress $TCPIPport -Name $TCPIPport } else { throw ("Printer Port '{0}' not found exception!" -f $TCPIPport) } } else { Write-Verbose ("Printer port '{0}' found." -f $TCPIPport) if ($PSBoundParameters.Verbose.IsPresent) { Get-PrinterPort | where Name -eq $TCPIPport } } $printers = Get-CimInstance -Class Win32_printer | where name -like $printerName if ($printers.count -ne 0) { foreach ($printer in $printers) { if ($printer.PortName -ne $TCPIPport) { Write-Verbose ("Setting Printer '{0}' port from '{1}' to '{2}'" -f $printer.Name, $printer.PortName, $TCPIPport) $printer.PortName = $TCPIPport } else { Write-Verbose ("Printer '{0}' port '{1}' was already '{2}'" -f $printer.Name, $printer.PortName, $TCPIPport) } } } else { throw ("Printer name '{0}' not exist exception!" -f $printerName) } } }
まとめ
なぜ Set-PrinterPort が既定でないのか謎ですね。海外のフォーラムでも困っている人が多いようなので、日本語記事にしてみました。
お役に立てば何よりです。