Wir kennen doch alle die nervige Situation, in der wir plötzlich sämtliche unserer erstellten Powershell oder Batchscripte in der Serverlandschaft aktualisieren müssen. Die Menge der Server entscheidet ob es eine Qual für uns wird oder nur eine kurze Nummer bleibt.
Sind die Scripte aktualisiert, fällt oft beim Ausführen der Powershell-Scripte auf den Servern aus, dass mindestens ein Server einen Sonderfall darstellt und das Script zum Fehler führt.
Also beginnt der ganze Spaß wieder von vorne…
Ich erledige sehr viele wiederkehrende Aufgaben und Prozesse per Powershell und muss des Öfteren meine bestehende Scripte erweitern oder austauschen. Die Serverlandschaft umfasst etwa 1200-1500 Windows Server (okay, meine Scripte laufen zum Glück nicht auf jeden Server 😉 ) was das ganz schnell zur Qual werden kann.
Um mich von diesen Qualen zu erlösen, habe ich mir ein weiteres Powershell-Script geschrieben welches Scripte ausrollt und im Anschluss per scheduled Tasks ausführt. Seitdem läuft das Deployment der Scripte locker und flockig, ganz nebenbei.
Wie das Powershell-Script funktioniert
Mein Deployment-Script erfüllt zwei Aufgaben, kopieren und anschließend das Starten der neuen Version. Manchmal reicht es auch aus nur Scripte zu aktualisieren, weshalb man das über die beiden folgenden Variablen steuern kann.
$copy_files=1 # 1=enable copy 0=disable copy
$start_scheduled_tasks=1 # 1=start script 0=disable
Quelle, Ziel und scheduled Tasks wird via verschachteltem Array festgelegt: $script_sources, $script_tasks, $script_targets
$script_sources=@{"scriptname1.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
scriptname2.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
}
$script_tasks=@{"scriptname1.ps1"="Serverinventory";
"scriptname2.ps1"="AD-Export";
}
$script_targets=@{"scriptname1.ps1"=@{
"server1_fqdn"="\c$\scripts";
"server2_fqdn"="\c$\scripts";
};
"scriptname2.ps1"=@{
"server3_fqdn"="\c$\scripts";
"server4_fqdn"="\c$\scripts";
}
}
Folgender Powershell Code erzeugt folgende Ergebnisse:
- Quelle ($script_sources): Serverinventory.ps1 => C:\Scripts\DeployScripts\scripts_for_deployment\
- Ziel ($script_targets): Serverinventory.ps1 => \dc12.pri.de\c$\scripts
- scheduled Task ($script_tasks): für das Script „Serverinventory.ps1“ lautet „Serverinventory“
$script_sources=@{"Serverinventory.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
#"AD-export.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
}
$script_tasks=@{"Serverinventory.ps1"="Serverinventory";
#"AD-export.ps1"="AD-Export";
}
$script_targets=@{"Serverinventory.ps1"=@{
"dc12.site1.local"="\c$\scripts";
"dc13.site1.local"="\c$\scripts";
};
<#"AD-export.ps1"=@{
"wfile01.site1.local"="\c$\scripts";
"wfile01.site2.local"="\c$\scripts";
}#>
}
Die Angaben für das Zweite Script sind auskommentiert.
das komplette Powershell-Script – Version 1
# Requirements:
# - powershell 2.0
# - need to run under domain admin user
#
# Configuration:
# - configure only
# -> $script_sources
# -> $script_tasks
# -> $script_targets
# -> $copy_files
# -> $start_scheduled_tasks
#
#### Configuration ####
$script_version="20190315"
$copy_files=1
$start_scheduled_tasks=1
$script_sources=@{"Serverinventory.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
#"AD-export.ps1"="C:\Scripts\DeployScripts\scripts_for_deployment\";
}
$script_tasks=@{"Serverinventory.ps1"="Serverinventory";
#"AD-export.ps1"="AD-Export";
}
$script_targets=@{"Serverinventory.ps1"=@{
"dc12.site1.local"="\c$\scripts";
"dc13.site1.local"="\c$\scripts";
};
<#"AD-export.ps1"=@{
"wfile01.site1.local"="\c$\scripts";
"wfile02.site1.local"="\c$\scripts";
}#>
}
$scriptname="FLEET_update-scripts_start-tasks.ps1"
foreach ($scriptfile in $script_targets.Keys){
$script_name=$scriptfile
write-host "-"$scriptfile
foreach ($key in $script_targets.$scriptfile.Keys){
if($copy_files -eq 1){
$script_target_server=$key
$script_target_folder=$script_targets.$scriptfile.$key
$source=$script_sources.$scriptfile+$scriptfile
$destination="\\"+$script_target_server+$script_target_folder
write-host "-> copy $source to $destination"
}
if(Test-Connection $script_target_server -Count 1){
if($copy_files -eq 1){
$tmp=$destination+"\"+$scriptfile
$dir=Get-ChildItem -Path $tmp
write-host "--> old LastWriteTime: "$dir.LastWriteTime" / old filesize:"$dir.Length
Copy-Item -Path $source -Destination $destination -Force
$dir=Get-ChildItem -Path $tmp
write-host "--> new LastWriteTime: "$dir.LastWriteTime" / new filesize:"$dir.Length
}
if($start_scheduled_tasks -eq 1){
write-host "-- start scheduled task: "$script_tasks.$scriptfile.ToString()
SCHTASKS /run /s $script_target_server /TN $script_tasks.$scriptfile.ToString()
write-host "-----------------------"
}
}else{
write-host "- ERROR: $script_target_server not available"
}
}
}
weitere Beiträge ähnlich Dateien mit Powershell verteilen
- Mit Powershell Systemdaten von Windows Systemen auslesen
- Powershell Programmierung – Tipps für verständliche Scripte
- Mit Powershell alle SCCM Clients auslesen
- WMI-Filter Zusammenstellung
- Active-Directory Clients mit Powershell inventarisieren
- Userprincipalname mit Powershell vervollständigen
- AD-User und AD-Gruppen mit Powershell bearbeiten
- alte Dateien löschen mit Powershell
- verbundene Drucker per Powershell als CSV auslesen
- sämtliche Computer der Active-Directory neu starten
- Passwörter der AD-Accounts mit Set-ADAccountPassword setzen
- invoke-command – Troubleshooting
- Anmeldedaten der geplanten Aufgaben mit Powershell ändern
- Computer mit Powershell zur Active-Directory hinzufügen (Add-Computer)
- Dateien und Ordner nach Alter löschen mit Powershell und Batch