実行時に指定されたコンピューターにリモートで静的 IP アドレスを割り当てる Powershell 関数を作成しようとしています。私はいくつかの調査を行い、Win32_NetworkAdapterConfiguration クラスを見つけました。これはまさに私が必要としているもののようです。そこで私は腰を下ろし、自分で関数を書きました:
Function Set-StaticIPAddress
{
param
(
[Parameter(Mandatory = $true,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true)]
[String] $ComputerName
,
[Parameter(Mandatory = $true,
Position = 1)]
[Alias("IPv4Address")]
[String] $IPAddress
,
[Parameter(Position = 2)]
[String] $SubnetMask = "none"
,
[Parameter(Position = 3)]
[String] $DefaultGateway = "none"
,
[Parameter(Position = 4)]
[String[]] $DNSServers = ("172.16.1.36","172.16.1.78")
,
[Parameter(Position = 5)]
[PSCredential] $Credential
)
process
{
# There's some error-checking here that I've snipped out for convenience
Write-Verbose "Testing connection to $ComputerName"
if (-not (Test-Connection $ComputerName))
{
Write-Error "Unable to connect to $ComputerName."
return
}
Write-Verbose "Obtaining remote WMI reference"
if ($Credential)
{
$wmi = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IPEnabled = 'True'" -Credential $Credential
} else {
$wmi = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IPEnabled = 'True'"
}
Write-Verbose "Attempting to set DNS servers"
$wmi.SetDNSServerSearchOrder($DNSServers)
Write-Verbose "Attempting to set dynamic DNS registration"
$wmi.SetDynamicDNSRegistration($true)
Write-Verbose "Attempting to set static IP address and subnet mask"
$wmi.EnableStatic($IPAddress, $SubnetMask)
Clear-DnsClientCache #This may not be necessary; I added it as a troubleshooting step
Write-Verbose "Attempting to set default gateway"
$wmi.SetGateways($DefaultGateway, 1)
Write-Output $wmi
}
}
問題は、EnableStaticメソッドが値 (成功コードまたは失敗コード) を返さないことです。この機能を隣のマシンでテストし、スクリプトが「静的 IP アドレスとサブネット マスクの設定を試行中」の段階でまだ待機している間に、マシンの構成をプルアップし、静的 IP とサブネットを見つけました。マスクセット。デフォルト ゲートウェイはありませんでした (これは、スクリプトがそこまで進んでいないため、当然のことです)。デフォルト ゲートウェイが見つからなかったため、問題のコンピューターにはネットワーク アクセスがありませんでした。
また、インタラクティブシェルから同じコマンドを実行しようとしましたが、同じコマンドで同じ「フリーズ」が発生します。
$wmi.EnableStatic($IPAddress, $SubnetMask)
おそらく、ネットワーク アダプターの構成を変更すると、リモート WMI 接続が切断されると思います。静的 IP アドレスの割り当てを 100% リモートでスクリプト化できるように、これを機能させる方法はありますか?
編集: ScriptBlock オブジェクトを作成し、Invoke-Command を使用してリモート コンピューターに送信する別の試みを MacGyvered しました。IP アドレスの配列を文字列リテラル (引用符を含む) に変換するには、興味深いフットワークを実行する必要がありましたが、スクリプト ブロックの構文が正しいことなどを確認できました。残念ながら、この方法を実行すると、PS ウィンドウは、(IP アドレスが変更されたため) ネットワーク接続が失われ、スクリプト ブロックが正常に完了しないというメッセージを表示します。
$wmiLiteral = '$wmi' # used so the script block actually creates and references a variable, $wmi
$script =
"$wmiLiteral = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter ""IPEnabled = 'True'"";
$wmiLiteral.EnableStatic(""$IPAddress"", ""$SubnetMask"");
$wmiLiteral.SetGateways(""$DefaultGateway"", 1);
$wmiLiteral.SetDNSServerSearchOrder($DNSServersList);
Write-Output $wmiLiteral"
Write-Verbose "Script block:`n-------------`n$script`n---------------"
$scriptBlock = [scriptblock]::Create($script)
Write-Verbose "Testing connection to $ComputerName"
if (-not (Test-Connection $ComputerName))
{
Write-Error "Unable to connect to $ComputerName."
return
}
Write-Verbose "Invoking scriptblock"
if ($Credential)
{
$output = Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock -Credential $Credential
} else {
$output = Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock
}