Wer sich intensiver mit der PowerShell befasst gelang über kurz oder lang an den Punkt, dass er Rechner an entfernten Standorten und/oder mehrere Rechner parallel mit einem Script konfigurieren möchte. An dieser Stelle werden wir auf grundlegende Punkte zur Remoteadministration via PowerShell eingehen.
Eine der scheinbar einfachen Möglichkeiten Code auf einem entfernten System auszuführen stellt das Cmdlet Invoke-Command dar. Betrachten wir hierzu zunächst einen Code, welcher IPv6 auf einer Auswahl von Remotesystemen deaktiviert.
Code
$ServerListe="SVR1","SVR2","SVR3"
$Suffix= ".Test.DNS.Suffix"
foreach($Server in $ServerListe){
$DNSMS= $Server + $Suffix
Invoke-Command -ComputerName $DNSMS -ScriptBlock {New-ItemProperty -Path HKLM:\system\CurrentControlSet\services\TCPIP6\Parameters -PropertyType DWord -Value 255 -Name DisabledComponents}
}
Alternativ kann das Script noch um ein wenig "Intelligenz" erweitert werden. Im folgenden findet zu Beginn des Scripts ein Abschnitt mit den zu nutzenden Variablen. Anschließend wird diese im Scriptblock verwendet. Die Reihenfolge der Argumentenliste ist hierbei entscheidend, da selbige über Position innerhalb des Default-Arrays Args entscheidet.
Code
$ServerListe="SVR1","SVR2","SVR3"$Suffix= ".Test.DNS.Suffix"
$RegPath = "HKLM:\system\CurrentControlSet\services\TCPIP6\Parameters"
$RegType = "DWord"
$RegValue = "255"
$RegName = "DisabledComponents"
foreach ($Server in $ServerListe){
$DNSMS= $Server + $DNSSuffix
Invoke-Command -ComputerName $DNSMS -ScriptBlock {New-ItemProperty -Path $Args[0] -PropertyType $Args[1] -Value $Args[2] -Name $Args[3]} -ArgumentList $RegPath,$RegType,$RegValue,$RegName
}
Das Script ist soweit noch nicht hübsch - aber es funktioniert - fast... Im Ablauf des Scripts ist erkennbar, dass eine Überprüfung der einzutragenden Keys nicht stattfindet. Dies führt wiederum zu unerwünschten Fehlermeldungen während des Ablaufes. Dieses ist im Folgenden leicht zu beheben.
Code
$ServerListe="SVR1","SVR2","SVR3"$
Suffix= ".Test.DNS.Suffix"
$RegPath = "HKLM:\system\CurrentControlSet\services\TCPIP6\Parameters"
$RegType = "DWord"
$RegValue = "255"$
RegName = "DisabledComponents"
foreach ($Server in $ServerListe){
$DNSMS= $Server + $DNSSuffix
Invoke-Command -ComputerName $DNSMS -ScriptBlock {$RegExists = Get-ItemProperty -path $Args[0] -Name $Args[3] -ErrorAction SilentlyContinue If($RegExists -eq $Null){New-ItemProperty -Path $Args[0] -PropertyType $Args[1] -Value $Args[2] -Name $Args[3]}} -ArgumentList $RegPath,$RegType,$RegValue,$RegName
}
Ohne das Script noch zu erweitern, ist hier bereits erkennbar, dass die Nutzung des Default-Array $Args bei komplexeren Scripts an sein Grenzen stößt. Zumindest der Entwickler wird auf die Dauer die Lust am Abzählen der Reihenfolgeposition verlieren. Im folgenden Code wurden die Variablen innerhalb eines Parameterblocks innerhalb des Scriptblocks definiert. Die Benennung ist somit transparent und der Code leichter nachzuvollziehen.
Code
$ServerListe="SVR1","SVR2","SVR3"$
Suffix= ".Test.DNS.Suffix"
foreach ($Server in $ServerListe){
$DNSMS= $Server + $DNSSuffix
Invoke-Command -ComputerName $DNSMS -ScriptBlock {
Param(
$RegPath = "HKLM:\system\CurrentControlSet\services\TCPIP6\Parameters",
$RegValue = "255",
$RegType = "DWord",
$RegName = "DisabledComponents")
$RegExists = Get-ItemProperty -path $RegPath -Name $RegName -ErrorAction SilentlyContinue
If($RegExists -eq $Null){New-ItemProperty -Path $RegPath -PropertyType $RegType -Value $RegValue -Name $RegName}
}
}