Automatisierte Aktualisierung der GPOs über RDP
Hier die Vorgeschichte warum ich GPOs zusätzlich über den Aufgabenplaner aktualisiere.
Ich hatte das Problem, dass mir immer wieder Rechte fehlten um VM Clients zu starten oder / und zu konfigurieren. Die Ursache liegt daran, dass ich die notwendigen Rechte des Hyper-V Accounts über Gruppenrichtlinien verteile. Nach Analyse habe ich über das Web fest gestellt, dass ich mit meinen Problem nicht alleine bin. Durch das ich nur Lösungen gefunden habe in der ich jeden Hyper-V Host manuell konfigurieren muss habe ich mich für dieses Skript entschieden.
Damit das Skript erfolgreich läuft, sind folgende Positionen notwendig:
- Der Account für die Ausführung im Aufgabenplaner muss das Recht Anmelden als Dienst besitzen (Lokale Sicherheitsrichtlinien / Zuweisung von Benutzerrechten / Anmelden als Stapelverarbeitungsauftrag)
- Das Account-Passwort für die Aktualisierung der Gruppenrichtlinien
Dieses wird verschlüsselt abgelegt, siehe passwort-in-datei-ueber-powershell-erstellen-speichern- Der Account für die Ausführung des Aufgabenplaner und der für die Aktualisierung der GPOs sollte der gleiche sein und sich mindestens ein mal am Domänencontroller angemeldet haben. Dies ist notwendig für die Ablage des Passworts.
- Ausführungsrecht des Skripts. Hier haben Sie die Möglichkeit mit dem Befehl
Set-ExecutionPolicy Unrestrictedentsprechende Rechte zu setzen. Dieser Befehl sollt aus Sicherheitsgründen nicht eingesetzt werden.
Die Sichere Methode ist, das Skript zu signieren. Siehe powershell-skript-signieren- Recht für die Ausführung einrichten
powershell -ep RemoteSigned -file MyScript.ps1
Die im Skript Fett gekennzeichneten Felder sind anzupassen.
# PowerShell Automatisierte Aktualisierung der GPOs ueber RDP 1.0.0 # (c) Siegfried Paul 2014 function Update-GPO{ # .SYNOPSIS Aktualisiertung GPUpdate AD Hyper-Vs .DESCRIPTION Hyper-V Server, die in der Domaene integriert sind und die Rechte ueber GPO gesteutert werden hat der Account "NT Virtual Machine\Virtual Machines" nur solagen die notwendigen Rechte wie die GPOs gueltig sind. Aktualisiert ueber GPUpdate alle Hyper-V Systeme die in der AD hinterlegt sind umd mit dem Namen HV beginnen. Im Fehlerfall wird eine E-Mail an mail@mail.de versendet. .PARAMETER SystemName Name des Sysetms auf dem es ausgefuehrt wird. Parameter ist hilfreich wenn fehler auftreten. .PARAMETER SendEMailSuccess Wird der Parameter $true mit uebergeben und der Durchlauf ist erfolgreich wird eine positive E-Mail versendet. Im Standard ist der Wert $false belegt Es koennen die Parameter $true oder $false uebergeben werden. .PARAMETER EMailTo Die Empfaenger-Adresse fuer einen erfolgreichen und fehlerhaften Durchlauf. Im Standard ist der Wert mit der Adresse mail@mail.de belegt. .EXAMPLE Update-GPO -SystemName [Systemname] Hier handelt es sich um den Systemnamen des Domain Controllers. Im Standard wird bei einem Fehlerfall eine E-Mail versendet. Zur Identifizierung bei mehreren Systemen sollte dieser Parameter mit übergeben werden. .EXAMPLE Update-GPO -SendEMailSuccess $true Aktualisiert alle Systeme mit Mail-Versand des erfolgreichen Durchlaufs .EXAMPLE Update-GPO -EMailTo $true Aktualisiert alle Systeme mit Mail-Versand des erfolgreichen Durchlaufs #> # Uebergabeparameter PARAM( [String][Parameter(Mandatory=$false,HelpMessage="Name des Domain Controllers")]$SystemName = "System unbekannt", [String][Parameter(Mandatory=$false,HelpMessage="E-Mail Empfaengeradresse")]$EMailTo = "mail@mail.de", [Bool][Parameter(Mandatory=$false,HelpMessage="E-Mail Versand bei erfolgreicher ausfuehrung")]$SendEMailSuccess = $false ) # Konsolenausgabe $Text = Get-Date "Start - $Text" ### # Anpassungen ### # Catch - Mail-Variable $EMailFrom = "mail@mail.de" $EMailServer = "smtp.mail.de" $EMailPort = 25 $SystemInfoText = "System unbekannt" $MailSubject = "GPUpdate - $Systemname" # Filter für LDAP $LDAPFilter = "HV*" # RDP Zugangsdaten $user = "domanin\administrator" # Passwortdatei $Text = "Passwortdatei pruefen" $PasswordDatei = "$env:USERPROFILE\spsoffice-Administrator.txt" if(-Not(Test-Path $PasswordDatei)){ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-Message: Die Passwortdatei wurde nicht gefunden.`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } try{ # Einlesen der Systeme basierend auf LDAP-Filter $Text = "Einlesen der Systeme basierend auf LDAP-Filter" # Konsolenausgabe $Text $cn = Get-ADComputer -LDAPFilter "(name=$LDAPFilter)" } catch{ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-StackTrace: $FailedItem`r`n Fehler-Message: $ErrorMessage`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } try{ # Passwort auslesen $Text = "Passwort auslesen" # Konsolenausgabe $Text $PWord = Get-Content $PasswordDatei | ConvertTo-SecureString } catch{ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-StackTrace: $FailedItem`r`n Fehler-Message: $ErrorMessage`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } try{ # RDP Zugangsdaten generieren $Text = "RDP Zugangsdaten generieren" # Konsolenausgabe $Text $Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord } catch{ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-StackTrace: $FailedItem`r`n Fehler-Message: $ErrorMessage`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Breas.pk } try{ # RDP-Verbindungen aufbauen - siehe $cn $Text = "RDP-Verbindungen aufbauen" # Konsolenausgabe $Text $session = New-PSSession -cn $cn.name -cred $Credential } catch{ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-StackTrace: $FailedItem`r`n Fehler-Message: $ErrorMessage`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } try{ # Befehl auf RDP System ausfuehren - gpupdate $Text = "Befehl auf RDP System ausfuehren" # Konsolenausgabe $Text icm -Session $session -ScriptBlock {gpupdate /force} } catch{ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $Text = "$Text`r`nFehler-StackTrace: $FailedItem`r`n Fehler-Message: $ErrorMessage`r`n" $MailSubject = "Error - $MailSubject" # Konsolenausgabe $Text Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } $Text = "GPUpdate wurde erfolgreich ausgefuehrt" # Konsolenausgabe $Text # Mailversand bei erfolgreicher ausfuehrung if($SendEMailSuccess -eq $true){ $FailedItem = $_.Exception.StackTrace $ErrorMessage = $_.Exception.Message $MailSubject = "Success - $MailSubject" Send-MailMessage -From $EMailFrom -To $EMailTo -Subject $MailSubject -SmtpServer $EMailServer -Port $EMailPort -Body $Text Break } }
Taskmanager
Der Aufruf erfolgt im Taskmanager wie folgt
Programm: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Argumente:
Update-GPO -SystemName NAMEDOMAINCONTROLLER *> "C:\PowerShell\Update-GPO.log" -SendEMailSuccess $true