Quantcast
Channel: PowerShell – faq-o-matic.net
Viewing all 102 articles
Browse latest View live

Berichte über Gruppenrichtlinien erzeugen

$
0
0

Schon seit vielen Jahren gibt es über die GPMC (Group Policy Management Console) die Möglichkeit, Berichte über Gruppenrichtlinien und ihre einzelnen Einstellungen zu erzeugen. Erledigte man dies früher mit den GPMC-Skripten auf VBScript-Basis, ist diese Funktion mit Windows Server 2008 in die PowerShell gewandert.

Für kleine Umgebungen kann die integrierte Option interessant sein, alle Gruppenrichtlinien in einen einzelnen Bericht zu exportieren:

Get-GPOReport -All -Domain "sales.contoso.com" -ReportType HTML -Path "C:\GPOReports\GPOReportsAll.html"

Das kommt in größeren Netzwerken schnell an eine Grenze, denn der Report kann -zig Megabytes groß werden, was kaum noch handhabbar ist. In solchen Fällen behilft man sich am besten mit Einzelreports. Ein recht einfaches Piping zweier PowerShell-Kommandos hilft hier weiter:

Get-GPO -all | % { Get-GPOReport -GUID $_.id -ReportType HTML -Path "C:\GPOReports\$($_.displayName).html" }

Um parallel noch eine Übersicht zu erhalten, welches GPO an welchen Container gebunden ist, eignet sich ein kleiner Report mit José. Dazu öffnet man ein CMD-Fenster, wechselt in das José-Verzeichnis und ruft dort Folgendes auf:

cscript //nologo //u JoseExec.vbs /d:!Gruppenrichtlinien.txt /r:Gruppenrichtlinien.html

Der José-Report findet sich dann im Unterordner “Reports”.


“Objekt vor zufälligem Löschen schützen” per PowerShell

$
0
0

Seit vielen Jahren bietet das Standard-AD-Tool “Active Directory-Benutzer und -Computer” eine Option, wichtige Container vor versehentlichem Löschen zu schützen:

[“Objekt vor zufälligem Löschen schützen” per Skript setzen | faq-o-matic.net]
https://www.faq-o-matic.net/2010/05/21/objekt-vor-zuflligem-lschen-schtzen-per-skript-setzen/

In einem Projekt habe ich festgestellt, dass sich dies nun auch per PowerShell recht simpel erreichen lässt:

Get-ADOrganizationalUnit -SearchBase 'name -like OU=MeineOU' | Set-ADObject -ProtectedfromaccidentialDeletion $true

Client Hyper-V: Automatische Checkpoints abschalten

$
0
0

Seit einigen Versionen erzeugt Client Hyper-V (also die Hyper-V-Variante, die unter Windows 10 läuft) von neu erzeugten VMs automatische Checkpoints (umgangssprachlich auch als “Snapshots” bezeichnet). Das geschieht immer dann, wenn man eine solche VM startet und soll es in Test- und Entwicklungsszenarien ermöglichen, einfach und schnell die betreffende VM auf einen definierten Stand zurückzusetzen. Das ist in manchen Situationen sicher praktisch, aber oft stört es, denn u.a. führt es dazu, dass beim Beenden der VM der Checkpoint wieder aufgelöst wird, was einige Zeit dauern kann.

Die Funktion gibt es auch auf dem Server, dort ist sie aber standardmäßig deaktiviert. In Windows 10 hingegen ist sie immer aktiv, man kann sie nur pro VM abschalten. Eine zentrale Konfiguration zum Deaktivieren dieses Features gibt es nicht.

Da mir die Auto-Checkpoints eher im Weg stehen, habe ich einen Weg gesucht, die Voreinstellung zu ändern und bin auf einen Workaround gestoßen: Ich weise Windows an, beim Erzeugen einer neuen VM die betreffende Option sofort abzuschalten. Das reicht mir völlig aus.


Der Trick besteht darin, das Ereignisprotokoll, die Aufgabenplanung und ein kurzes PowerShell-Skript einzusetzen. Beim Erzeugen einer neuen VM schreibt Windows das Event 18304 in eines der Hyper-V-Eventlogs. An dieses Event kopple ich im Task Scheduler eine Aufgabe, die mein PowerShell-Skript aufruft. Dieses erhält den Namen der VM und kann so die Option deaktivieren. So geht’s:

Der Task

Die folgende XML-Datei (Download findet sich unten) legt eine Aufgabe an, die sich an das Event 18304 im passenden Eventlog als Auslöser hängt. Die Datei ist leicht erweitert, denn von sich aus geben Taks keine Details an die aufgerufenen Programme weiter. Möglich ist das aber sehr wohl, wie folgende Blogposts beschreiben:

[Reference The Event That Triggered Your Task – Otto Helweg – Management Matters]
https://blogs.technet.microsoft.com/otto/2007/11/09/reference-the-event-that-triggered-your-task/

[Task scheduler – Event Log Trigger – Include Event Data in mail | Blog for reference – Vijred]
https://vijredblog.wordpress.com/2014/03/21/task-scheduler-event-log-trigger-include-event-data-in-mail/

In der zunächst manuell erzeugten und dann exportierten Aufgabe fügt man also eine “ValueQuery” hinzu und definiert so die zu übergebenden Werte. Diese lassen sich dann mit der Syntax $(Variable) an das Programm übergeben. So sieht das dann aus:

image

Hier also die XML-Datei, reduziert auf das Wesentliche:

<?xml version=“1.0″ encoding=“UTF-16″?>
<Task version=“1.2″ xmlns=“
http://schemas.microsoft.com/windows/2004/02/mit/task“>
   <Triggers>
     <EventTrigger>
       <Enabled>true</Enabled>
       <Subscription>&lt;QueryList&gt;&lt;Query Id=“0″ Path=“Microsoft-Windows-Hyper-V-VMMS-Admin“&gt;&lt;Select Path=“Microsoft-Windows-Hyper-V-VMMS-Admin“&gt;*[System[Provider[@Name=’Microsoft-Windows-Hyper-V-VMMS‘] and EventID=18304]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
      <ValueQueries>
         <Value name=“VMName“>Event/UserData/VmlEventLog/VmName</Value>
       </ValueQueries>

     </EventTrigger>
   </Triggers>
   <Actions Context=“Author“>
     <Exec>
       <Command>powershell.exe</Command>
       <Arguments>-noprofile -ExecutionPolicy Unrestricted -file „E:\Daten\VM-Event\Disable-VMAutoCheckPoint.ps1“ -VMName $(VMName)</Arguments>
     </Exec>
   </Actions>
</Task>

Diese XML-Datei passt man in Zeile 15 an und hinterlegt dort den Pfad, an dem das PowerShell-Skript hinterlegt ist. Dann importiert man die Datei als neue Aufgabe.

Das Skript

Fehlt noch das PowerShell-Skript. Das ist eigentlich sehr simpel, denn es verändert nur eine Option an der VM. Dazu braucht es allerdings eine Parameterübergabe, die hier den Regeln schönen Codings entsprechend ausgeführt ist.

param(
  [string]$VMName
)
Set-VM -Name $VMName -AutomaticCheckpointsEnabled $false

# uncomment the follwing line and set a valid path to have the VM name logged
# $VMName | Out-File -FilePath E:\Daten\VM-Event\MyResult.txt -Append

Dieses Skript hinterlegt man an dem Pfad, der in der XML-Datei angegeben ist. Auf gemeinsam genutzten Systemen sollte man ggf. die Berechtigungen des Ordners anpassen, damit einem niemand ein manipuliertes Skript unterschiebt.

Der Download

Hier die beiden Skripte zum Download:

Note: There is a file embedded within this post, please visit this post to download the file.

Los geht’s!

Das war es auch schon. Erzeugt man nun eine neue VM, so öffnet sich kurz ein PowerShell-Fenster, das gleich wieder verschwindet. Danach ist bei der neuen VM die betreffende Option abgeschaltet:

image

Powershell: Active-Directory-Cmdlets basierend auf ADSI

$
0
0

Möchte man z.B. AD Objekte auf einem Client ohne RSAT (Remote Server Administration Tools) abfragen, so bleibt einem lediglich der Zugriff auf die seit PowerShell v1.0 integrierten bzw. aus dem .NET Framework kommenden „ADSI“- und „ADSISearcher“-Klassen. Da der Umgang mit diesen nicht annährend so komfortable wie die Verwendung der Cmdlets aus dem Active Directory Snapin ist, habe ich einige Funktionen geschrieben, um dies zu vereinfachen. Die Funktionen findet man hier und die Parameter und Rückgabewerte der einzelnen Funktionen hier.

Natürlich ist das nur ein Bruchteil der über die ADSI-Schnittstelle möglichen Transaktionen, allerdings kann man anhand dieser weitere Funktionen schreiben.

Ein spannendes Beispiel ist, dass man z.B. über die Funktion „Add-GroupMemberByNetBIOS“ im Security-Context des Users ein neues Mitglied einer Gruppe hinzufügen kann, sofern der ausführende Benutzer das Attribut „member“ Gruppe bearbeiten darf. Dies kann man z.B. durch den Haken „Erlaube dem Besitzer die Mitgliederliste der Gruppe zu verändern“ in der Active Directory Users and Computers (ADUC) Konsole ermöglichen. Hierbei kann die SID auch aus einer anderen, mit dem aktuellen Forest vertrauten Domäne kommen. Sofern noch kein ForeignSecurityPrincipal für das neue Mitglied existiert, wird dies dabei von selbst erstellt und anstelle des Users berechtigt.

Führt man den Gedanken etwas weiter, wäre es hiermit zum Beispiel möglich, ein Self-Service-Tool für vereinfachte Gruppenverwaltung in PowerShell zu schreiben, welches auf jedem Client-PC auch ohne die Installation der Remote Server Administration Tools funktioniert.

Active Directory Computer Account Password Renewal

$
0
0

Jeder, der sich schon mal (intensiver) mit der Pflege einer Active-Directory-Domäne auseinandergesetzt hat, kann nicht abstreiten, dass z.B. Computerkonten oft länger als der eigentliche Computer leben. Möchte man dies verhindern, so gibt es viele Wege – einmal sollte dies ein klar definierter Workflow bei der Dekommissionierung eines Computers sein, andererseits ergibt es durchaus Sinn die aktiven Computerkonten zu überwachen. Entscheidet man sich dazu, dies per Powershell zu tun, stellte sich relativ schnell heraus, dass man dies am besten anhand des Attributes „pwdLastSet“ realisiert.

Eine kurze Abfrage mittels PowerShell zeigt uns auf, welche Computer schon länger als 30 Tage ihr Kennwort nicht geändert haben und noch über aktive Konten verfügen:

Get-ADComputer -Filter { Enabled -eq $true } -Properties pwdLastSet | Where-Object { [datetime]::fromFileTimeUTC($_.pwdLastSet) -le (Get-Date).AddDays(-30) } 

Hierbei wird einem schnell auffallen, dass Computerkonten dabei sind, die an dieser Stelle eigentlich nicht auftauchen sollten. In der Standardeinstellung (ab Windows NT) ändert ein Computer das Passwort seines Machine Accounts alle 30 Tage, dies passiert allerdings nur, wenn auch Konnektivität zum Domain Controller besteht und dieser zu der Zeit auch in der Lage ist, Passwortänderungen durchzuführen.

Möchte man dieses Intervall ändern, kann man dies mit der GPO „Domain member: Maximum machine account password age“ unter „Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options\“. Möglich wäre hier z.B. ein Wert von 14 Tagen. Circa 2 Wochen später sollte man über den oben aufgezeigten Befehl deutlich bessere Ergebnisse erzielen und kann diese zum Beispiel mit dem folgenden Befehl deaktivieren:

Get-ADComputer -Filter { Enabled -eq $true } -Properties pwdLastSet | Where-Object { [datetime]::fromFileTimeUTC($_.pwdLastSet) -le (Get-Date).AddDays(-30) } | Set-ADComputer -Enabled $false -Whatif

Der Parameter -Whatif versetzt das Cmdlet in eine Art Trockenlauf, um die Änderungen tatsächlich durchzuführen, muss dieser entfernt werden.

Wichtig dabei: Viele Unix Systeme, darunter u.a. Storage Systeme, werden diese Policy nicht verarbeiten (können). Ein häufig angetroffenes System ist zum Beispiel die Netapp Storage Virtual Machine auf ONTAP-Systemen. Hier kann man zwar den GPO Support einschalten, allerdings scheint die Verarbeitung dieser GPO in der aktuellen Version nicht implementiert zu sein (näheres dazu in diesem Dokument). Bei ONTAP kann dies wiederum manuell per CLI aktiviert werden, siehe diesen Artikel.

Einfache Dummy-Dateien in jedem Ordner

$
0
0

In einem Migrationsprojekt brauchte ich eine Ordnerstruktur mit je mindestens einer Datei, um diverse Dinge zu testen. Die Ordnerstruktur habe ich nach einem Export des Originals nachgebildet. Die ganzen Dateien wollte (und durfte) ich von dort aber nicht mitschleppen. Also behalf ich mir mit folgendem Skript, das je eine Datei pro Ordner erzeugt:

$FolderPath = 'E:\'
$Folder = Get-ChildItem -Path $FolderPath -Recurse
$Count = 0
foreach ($ThisFolder in $Folder.GetEnumerator()) {
  $Name = $ThisFolder.Name
  "I am a placeholder in folder $ThisFolder" | Out-File -FilePath ($ThisFolder.FullName + "\$ThisFolder-File.txt")
  $Count += 1
}
"$Count Dateien erzeugt."

Azure AD Identity umziehen

$
0
0

Hat man in der heutigen Zeit mit einer Active-Directory-Migration zu tun, so ist meist die eigentliche Migration der Computer und User das kleinste Übel. Durch die Anbindung diverser Systeme muss aber jede Identität eines Users in jedem angebundenen System berücksichtigt werden. Ein sehr gutes Beispiel hierfür ist Office 365, respektive die Azure-Active-Directory-Identität eines Benutzers, an der in der durchschnittlichen Umgebung mindestens eine Mailbox, ein Sharepoint-Profil und ein Skype-for-Business-/Teams-Account hängt.

Ein praktisches Verfahren hierzu mit einer PowerShell-Funktion habe ich hier beschrieben:

[Azure AD Identity umziehen – michael wessel Blog]
https://blog.michael-wessel.de/2019/02/14/azure-ad-identity-umziehen/

Exchange Mailbox Delegation Automapping

$
0
0

Bei der Delegation von FullAccess-Berechtigungen auf einer Mailbox oder einer Shared Mailbox ist dem einen oder anderen sicher bereits aufgefallen, dass sich das Automapping nicht konsistent verhält. Untersucht man dies genauer, so fällt auf, dass lediglich die beim Erstellen der Mailbox vergebenen Delegationen auch Automapping aktiviert haben, nachträglich hinzugefügte haben dies nicht, zumindest sofern sie per Exchange Control Panel erteilt wurden.

Für das Automapping ist das Attribut „msExchDelegateListLink“ auf dem Active-Directory-Konto der freizugebenen Mailbox verantwortlich. Dieses Attribut beinhaltet die DistinguishedNames aller Mailboxen, welche beim Start von Outlook dieses Postfach automatisch eingebunden kriegen sollen. Das Attribut an sich hat zuerst jedoch nichts mit der eigentlichen FullAccess-Berechtigung zu tun, es reicht also nicht, die zu autorisierenden DistinguishedNames dort einzutragen. Möchte man alle Mailboxen, die nachträglich mit FullAccess für ein Postfach über das Exchange Control Panel autorisiert wurden, auf Automapping umstellen, so schafft einem PowerShell wie gewohnt Abhilfe.

Hier könnte man meinen, dass der Befehl „Get-Mailbox -Identity „xyz“ | Get-MailboxPermission“ auch ein Attribut zurückliefert, welches die Automapping Einstellungen pro Freigabe anzeigt – tja, das wäre wohl auch zu einfach. Der einfachste Weg, sich per Powershell alle auf Automapping gestellten Freigaben eines Postfaches anzuzeigen, ist der folgende Befehl:

Get-ADUser -Identity (Get-Mailbox -Identity „xyz“ | Select-Object -ExpandProperty userPrincipalName) -Properties msExchDelegateListLink | Select-Object -ExpandProperty msExchDelegateListLink

Möchte man nun alle bereits erteilten FullAccess-Berechtigungen auf Automapping umstellen, so hilft dieses von mir geschriebene Script aus:

https://github.com/RobinBeismann/PowerShell-Scripts/blob/master/Scripts/MS-Exchange/Fix-Automapping.ps1

Eine kleine Schwierigkeit ist, dass Get-MailboxPermission lediglich die objectSID der berechtigten Mailboxes anzeigt. Über Get-ADUser kann man diese aber auf ihre Mailboxes auflösen und die DistinguishedNames für das msExchDelegateListLink Attribut sammeln. Wichtig zu wissen ist, dass es sich um die SID des tatsächlichen Postfaches handelt, im Falle einer Linked Mailbox ist dies also nicht die ObjectSID sondern die msExchMasterAccountSid, diese Besonderheit wird von dem oben verlinkten Script bereits berücksichtigt.

Noch eine Randnotiz: Erstellt man die Mailbox Berechtigungen direkt per Add-MailboxPermission, so kann man das Automapping über den Parameter „-AutoMapping <$true | $false>“ steuern.


Powershell: Dynamische Logikabfragen

$
0
0

Bei einem aktuellen Projekt benötigte ich die Möglichkeit, mehrere Werte aus einer XML-Datei mit einem ebenfalls darin definierten Logikoperator zu vergleichen. Das Szenario dazu: In dem Projekt ist eine leichtgewichtige Softwareverteilung auf Skriptbasis im Einsatz, die beim Systemstart verschiedene Applikationen aktualisiert. Hier war noch etwas mehr Logik erwünscht, um Aktivitäten nur dann auszuführen, wenn bestimmte Bedingungen erfüllt sind.

Da der Code möglichst dynamisch und gut erweiterbar sein sollte, stellte sich heraus, dass der Logikoperator durch einen Scriptblock dynamisch in den Code eingefügt werden musste. Um dies zu ermöglichen, habe ich die Funktion Apply-CustomLogic() entworfen, welche aktuell die Operatoren „like“, „is“, „isnot“, „startswith“, „notstartswith“, „endswith“ und „notendswith“ unterstützt.

Drei kurze Cmdlet Beispiele dazu, die mit einer Funktion auf dieser Basis arbeiten:

Apply-CustomLogic(„startswith“,“faq-o-matic.de“,“faq“)  <- Ergebnis: $true

Apply-CustomLogic(„endswith“,“faq-o-matic.de“,“.de“)  <- Ergebnis: $true

Apply-CustomLogic(„notendswith“,“faq-o-matic.de“,“.de“) <- Ergebnis: $false

Ein typisches Code-Szenario dafür wäre: Mehrere Konditionen sowie Referenzwerte müssen aus einer XML-Datei ausgelesen und dann in Powershell interpretiert werden.

Die XML Datei beinhaltet dann folgendes:

<check type="RegistryValue" logic="StartsWith">
   <path>Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\</path>
   <key>Version</key>
   <value>14</value>
</check>
<check type="RegistryPathPresent" logic="Is">
   <path>Registry::HKEY_LOCAL_MACHINE\SOFTWARE\TeamViewer\</path>
</check>

Der Script-Part dazu sähe wie folgt aus:

[..]
#Check if a registry path is present
if($checkType -eq "RegistryPathPresent"){
   if(
	   !(Apply-CustomLogic -condition $check.Logic -V1 $true -V2 (Get-ItemProperty -Path $Check.Path -ErrorAction SilentlyContinue))
	 ){
	   Write-CustomWarning("Check $checkType for $($Check.Path)$($check.Key) is $IgnoreSoftware, supposed value is $($Check.Value), current value is $($Path.$($Check.Key))")
   }else{
	   Write-CustomLog("Check $checkType for $($Check.Path)$($check.Key) is $IgnoreSoftware, supposed value is $($Check.Value), current value is $($Path.$($Check.Key))")                
   }
}

#Check for a specific registry value
if($checkType -eq "RegistryValue"){
   if(
	   !($Path = Get-ItemProperty -Path $Check.Path -ErrorAction SilentlyContinue) -or
	   !(Apply-CustomLogic -condition $check.Logic -V1 $Path.$($Check.Key) -V2 $Check.Value)
   ){
	   Write-CustomWarning("Check $checkType for $($Check.Path)$($check.Key) is $IgnoreSoftware, supposed value is $($Check.Value), current value is $($Path.$($Check.Key))")
   }else{
		Write-CustomLog("Check $checkType for $($Check.Path)$($check.Key) is $IgnoreSoftware, supposed value is $($Check.Value), current value is $($Path.$($Check.Key))")
	}
}
[..]

Hierbei werden nun die Konditionen und Referenzwerte aus der XML-Datei gegen reale, per Powershell abrufbare Funktion oder Variablen geprüft. Um den Code dynamisch zu generieren, nutzt die Funktion die Funktion Create([string]) auf der Klasse [Scriptblock], um aus einem vorher zusammengesetzten String einen ausführbaren Code zu generieren. Dieser Code wird im Anschluss durch $scriptblock.Invoke() ausgeführt und wendet den vorher generierten Logikcode aus.

Zu finden ist diese Funktion hier:

https://github.com/RobinBeismann/PowerShell-Scripts/blob/master/Scripts/Snippets/Apply-CustomLogic.ps1

PowerShell Saturday Hannover am 05.10.2019

$
0
0

Schon zum dritten Mal veranstaltet die Powershell Usergroup Hannover jetzt den Powershell Saturday Hannover. Neben der inzwischen obligatorischen Einführung in Powershell haben wir wieder viele tolle Sprecher für die Veranstaltung eingeladen:

  • Dr. Tobias Weltner
  • Jan-Hendrik Damasche
  • Christoph Burmeister
  • Andreas Nick und Patrick Horn
  • Friedrich Weinmann
  • Martin Gudel

Der Powershell Saturday ist kostenlos und bietet für Teilnehmer spannende Themen und Möglichkeiten, sich bei einem Kaffee oder anschließend einem Bier zu vernetzen.

Die komplette Agenda und die Anmeldung findet Ihr unter https://www.meetup.com/de-DE/PowerShell-Usergroup-Hannover/events/262836522/.

SCCM: Status-Mail aus Task-Sequenz

$
0
0

In gewissen Fällen möchte man aus einer Task-Sequenz heraus eine Statusmail verschicken, hierbei führen wie gewohnt viele Wege zum Ziel.

Ein einfacher Weg ist hierbei natürlich PowerShell. Um den nötigen Customizing-Aufwand zu minimieren, habe ich ein Script geschrieben, welches den Computernamen, den Status des letzten Task-Sequenz-Schrittes und den Namen des aktuellen Schrittes automatisch abruft. Möchte man dieses Script einbinden, so braucht man lediglich einen „Run Powershell Script“ Step zu erstellen, wahlweise den Code als Package oder direkt zu hinterlegen und einen entsprechenden Namen zu setzen:

Sobald der Computer bei diesem Schritt ankommt, sendet er automatisch eine Mail in dem folgenden Format an die im Script hinterlegte Email Adresse: [Success]: Task Sequence „%Task Sequenz Name%“ on %Computername% (Step: „Status Mail: TS Success“)

Man kann diesen Schritt dann zum Beispiel an unterschiedliche Stellen in der Task Sequenz kopieren und z.B. abhängig von Task Sequenz Variablen entsprechende Statusmails versenden:

Hyper-V-VMs ohne Datenverlust entfernen

$
0
0

Wenn man eine Virtuelle Maschine (VM) im Hyper-V-Manager oder per PowerShell löscht, dann entfernt Hyper-V diese aus seiner Konfiguration, lässt die zugehörigen virtuellen Festplatten aber im Dateisystem. Das ist praktisch, falls man eine solche VM später noch einmal verwenden möchte, denn ihre Daten und der wichtigste Teil ihrer Konfiguration (nämlich das VM-Betriebssystem) bleiben so erhalten.

In manchen Situationen ist es aber hinderlich, dass die “äußere” Konfiguration der VM beim Löschen verschwindet. Dazu gehören die virtuellen CPUs, die RAM-Konfiguration und die virtuellen Netzwerkkarten, aber auch die eindeutige ID der VM. Zwar kann man diese “VM-Hülle” meist recht schnell neu erzeugen, aber auch das hat Nachteile. So entstehen dabei etwa neue virtuelle Netzwerkkarten, die das vorhandene VM-Betriebssystem neu einrichtet, wodurch die vorhandene IP-Konfiguration unwirksam wird.

Eine Abhilfe bestünde darin, eine solche VM vor dem Löschen zu exportieren. Den so erzeugten Export kann man später wieder importieren oder schlicht registrieren. Dadurch arbeitet die betreffende VM wieder wie vorher. Der Nachteil: Das ist ein wenig umständlich, außerdem ändern sich dadurch evtl. Speicherpfade.

Während man also eine vorhandene VM (die z.B. einfach komplett im Host-Dateisystem kopiert wurde) einfach registrieren kann, fehlt das Gegenstück, das “Ent-Registrieren”. Hier hilft ein kleines PowerShell-Skript, das die Konfigurationsdaten der VM vor dem Löschen sichert und sie danach wieder in den vorgesehenen Ordner zurück kopiert.

$VMName = Read-Host 'Enter VM name'
# get VM data
$VMData = Get-VM $VMName -ErrorAction SilentlyContinue
if (!$VMData) {
  "VM $VMName not found."
  Return
}
# get config folder
$VMConfLoc = $VMData.ConfigurationLocation

# save VM metadata
$VMBackupLoc = $VMConfLoc + '\_VMConf\'
Copy-Item -Path ($VMConfLoc + '\Virtual Machines') -Destination $VMBackupLoc -Recurse

# remove the VM
Remove-VM -Name $VMName -Force

# restore VM metadata
Copy-Item -Path ($VMBackupLoc + '*') -Destination ($VMConfLoc + '\Virtual Machines') -Recurse

# remove the backup folder
Remove-Item $VMBackupLoc -Recurse

"$VMName successfully unregistered." 
"Find its configuration data at $VMConfLoc"

Hier der Download:
Note: There is a file embedded within this post, please visit this post to download the file.

Gruppenrichtlinien pro OU anzeigen und dokumentieren

$
0
0

Vor einiger Zeit haben wir einen Tipp veröffentlicht, wie man die Gruppenrichtlinienobjekte (GPOs) einer Domäne in einzelnen Reports dokumentieren lassen kann:

[Berichte über Gruppenrichtlinien erzeugen | faq-o-matic.net]
https://www.faq-o-matic.net/2018/04/10/berichte-ber-gruppenrichtlinien-erzeugen/

Es gibt allerdings auch Situationen, in denen man nicht alle GPOs der gesamten Domäne braucht, sondern nur diejenigen in einem bestimmten OU-Zweig. Auch hier hilft die PowerShell.

Das folgende Skript gibt die Namen aller GPOs aus, die sich unterhalb einer bestimmten OU in der Domäne befinden. In der ersten Zeile gibt man diese OU in LDAP-Syntax an.

$SearchBase = 'OU=MyOU,DC=domain,DC=tld'
$GPOs = @()
$GPOsUnique = @()
$OUs = Get-ADOrganizationalUnit -SearchBase $SearchBase -Filter * 
foreach ($OU in $OUs) {
  $GPOs += $OU.LinkedGroupPolicyObjects
}
'GPOs linked in tree: ' + $GPOs.Count
$GPOsUnique = ($GPOs | Sort-Object -Unique)
'Unique GPOs linked in tree: ' + $GPOsUnique.Count 
$GPOsUnique

Und das zweite Skript geht noch einen Schritt weiter: Es erzeugt einen Report für jedes GPO und speichert diese Reports als einzelne HTML-Dateien ab. (Voraussetzung: Die RSAT-Tools müssen auf dem ausführenden Rechner installiert sein.)

$SearchBase = 'OU=MyOU,DC=domain,DC=tld'
$GPOs = @()
$GPOsUnique = @()
$OUs = Get-ADOrganizationalUnit -SearchBase $SearchBase -Filter * 
foreach ($OU in $OUs) {
  $GPOs += $OU.LinkedGroupPolicyObjects
}
'GPOs linked in tree: ' + $GPOs.Count
$GPOsUnique = ($GPOs | Sort-Object -Unique)
'Unique GPOs linked in tree: ' + $GPOsUnique.Count 

foreach ($GPO in $GPOsUnique) {
  $GPOName = ''
  $GPOName = (Get-ADObject -Identity $GPO).Name
  if ($GPOName) {
    $GPODisplayName = ''
    $GPODisplayName = (Get-GPO -Guid $GPOName -ErrorAction SilentlyContinue).DisplayName
    "Creating report for $GPODisplayName"
    Get-GPOReport -Guid $GPOName -ReportType Html -Path "$env:userprofile\Documents\$GPODisplayName.html"
  }
}

Hier ist der Download für beide Skripte:

Note: There is a file embedded within this post, please visit this post to download the file.

Get-HyperVInventory: New Download Source is Here

$
0
0

Some weeks ago, Microsoft have announced that they are going to shut down their TechNet Gallery very soon (that is: at the end of December, 2020). There is a small number of contributions that we have been involved with. Furtunately, the original license (MIT license) allows us to republish those contributions. So in the next days we are going to do this.

This contribution was first published in Microsoft’s TechNet Gallery. See the authors and copyright notices in the text below.

Get-HyperVInventory: Create inventory reports of Hyper-V environments

Overview

Get-HyperVInventory.ps1 is a PowerShell script to create documentation reports (HTML or plain text) of single Hyper-V host servers (including client Hyper-V on Windows 8 and later) or complete Hyper-V failover clusters.

Get-HyperVInventory reads configuration data from Hyper-V host servers and writes them to an HTML file or a plain text file in a structured way. It is designed to be an inventory and reporting tool. It does not include performance or health data.

The script does not change anything on the systems. It only reads data and writes a text file. Thus, it is not „harmful“ by itself. It may, however, create significant load on your host servers if you run it in a very large environment.

The reports may include confidential data. So you should make sure to handle the reports adequately.

The script has multiple operation modes that let you choose between a a full cluster inventory (including all host servers and all VMs), an inventory of just one host server (local or remote, including or excluding all VMs), a cluster core inventory or VM inventories.

This is only a small compilation of the data the script gathers:

  • Hyper-V failover clusters: cluster core data, cluster networks, cluster storage
  • Hyper-V host servers: OS details, CPUs (and cores), RAM, host networking, virtual switches, replication
  • VMs: general data, CPU, RAM, networking, disks, Integration Services, replication

See a sample report with the following link (mind: this is only the sample report, not the tool itself!)

Note: There is a file embedded within this post, please visit this post to download the file.

A screenshot of the menu

clip_image001

Download

Download the script here:

Note: There is a file embedded within this post, please visit this post to download the file.

New in version 2.4

The new version:

  • includes more data, especially for Windows Server 2016: Shielded VMs, VM Groups, Checkpoint type and some more
  • still runs with Windows Server 2012, 2012 R2 and 2016 – and with the client versions Windows 8, 8.1 and 10
  • includes Virtual Fibre Channel basic data (thanks to Sascha Loth)
  • includes the companion script Get-HyperVInventory-MultipleReports.ps1 to create separate reports automatically (since v 2.3)
  • tells you „what’s new“ in the README.txt file
  • ships with an optional signed version so you can be sure it is the original script

Platforms

This script has been developed and tested on Windows Server 2012 R2 and Windows Server 2016.

You need:

  • OS: Windows Server 2012, Windows Server 2012 R2 or Windows Server 2016, any edition capable of Hyper-V (slightly limited functionality in Windows Server 2012)
    for client Hyper-V: Windows 8, Windows 8.1 or Windows 10 with Hyper-V enabled
  • PowerShell 3.0 or higher (default in Windows Server 2012, v4.0 in 2012 R2)
  • Hyper-V role installed and configured
  • optional: Failover cluster role installed and configured
  • Run the script in a PowerShell session with elevated privileges. Your account needs Administrator privileges on each host to report on.
  • a folder to store the report (default: current user’s Documents folder, but you can specify any folder)

Attention

This script has not been designed for very large environments. It has not yet been tested in large environments, either.

As the script may create significant load (especially when there are many hosts in a cluster) please make sure that its execution will not harm your production environment. You can always run the script in one of the partial report modes to test it or to gather data from individual hosts. This should not have much impact on the respective server.

But keep in mind that you need to run the script with Administrator privileges so make sure that the script has not been modified by an attacker. You can report remote hosts but you must launch the script on a Hyper-V enabled computer.

The script has not been fully tested with a restricted user account. It may run and it may not.

Neither the author nor the company can provide any warranty for the script. Use at your own risk.

Usage

  • Set your PowerShell Execution Policy to „RemoteSigned“ at least. Depending on where your copy is stored you might need to set it to „Unrestricted“.
    Example: ‚Set-ExecutionPolicy RemoteSigned‘
  • Run the script like this in the powershell commandshell or PowerShell ISE:
    .\Get-HyperVInventory.ps1 [[-output] <String>] [[-mode] <String>] [[-format] <String>] [[-noview] <Boolean>] [[-remoteHost] <String>] [[-VMName] <String>] [<CommonParameters>]
  • Make sure to launch your PowerShell window or PowerShell ISE as Administrator.
  • You can launch the script without parameters, it will then ask for the mode to perform.
  • Run the script locally on a Hyper-V host server (or on one of the cluster hosts of the cluster you want to document) even if you want to document a different host.

Full online help and a readme file are included. A sample report is included as well.

Simple Reporting: If you need multiple reports that cover the cluster level, each host and each VM separately, use the companion script Get-HyperVInventory-MultipleReports.ps1. Make sure the script is stored in the same folder as Get-HyperVInventory.ps1 on one of your Hyper-V hosts, and launch it with administrator privileges. No parameters. The script then scans your environment and creates one HTML report per item (cluster, host, vm).

New (v2.4 and higher): There are two versions of the script. The one with the label „signed“ in its name is cryptographically signed by the main author so you can be sure it is the correct one. Rename it if you want to use it. This is optional, you can of course use the smaller unsigned version.

Future versions

The script will be further developed. We are planning:

  • Improvements to the report for better readability
  • Selected additional data

Authors

The script has been authored by Christopher Junker, Sascha Loth and Nils Kaczenski. The project was initiated by the german IT service company Michael Wessel Informationstechnologie GmbH in Hannover.

Was: <https://gallery.technet.microsoft.com/Get-HyperVInventory-Create-2c368c50/description>

Get-HyperVNetworkReport: New Download Source is Here

$
0
0

Some weeks ago, Microsoft have announced that they are going to shut down their TechNet Gallery very soon (that is: at the end of December, 2020). There is a small number of contributions that we have been involved with. Furtunately, the original license (MIT license) allows us to republish those contributions. So in the next days we are going to do this.

This contribution was first published in Microsoft’s TechNet Gallery. See the authors and copyright notices in the text below.

Get-HyperVNetworkReport: Create a visual overview of Hyper-V network connections

Overview

Hyper-V network connections build the core of virtual machine communication. While the basic concept of Hyper-V networking is not too hard to understand there is no simple visual representation in the operating system. This makes it hard for administrators to understand the relationship between physiscal network adapters, adapter teams, virtual switches, and virtual network adapters.

Get-HyperVNetworkReport creates a simple overview report of your host’s network environment. It groups the components into three logical layers:

  1. the host level (physical network adapters and NIC teams)
  2. the Hyper-V level (virtual Switches)
  3. the VM level (virtual network adapters of all VMs and of the Management OS)

The script can be launched without any parameters. Launch it as a local administrator. It creates an HTML report file in your Documents folder that can be opened with any browser. The script only reads data and writes an HTML file.

Platforms

This script has been developed on Windows Server 2012 R2 and Windows Server Technical Preview (Build 9841).

You need:

  • OS: Windows Server 2012, Windows Server 2012 R2 or Windows Server Technical Preview (Build 9841 or later), any edition capable of Hyper-V
  • PowerShell 3.0 or higher (default in Windows Server 2012, v4.0 in 2012 R2)
  • Hyper-V role installed and configured
  • Run the script in a PowerShell session with elevated privileges. Your account needs Administrator privileges to read the data.

Download

Note: There is a file embedded within this post, please visit this post to download the file.

Usage

You can run the script from a PowerShell command line or (preferred) from the PowerShell ISE. It does not require any parameters, then it opens the report automatically when it’s completed.

Add the parameter -noview $true to NOT open the report (fully automated mode).

Example:

.\Get-HyperVNetworkReport.ps1 -noview $true

Online help for the Get-Help command is included.

Author

The script has been authored by Nils Kaczenski. No warranty will be granted. The project was initiated by the German IT service company Michael Wessel Informationstechnologie of Hannover.

Was <https://gallery.technet.microsoft.com/Get-HyperVNetworkReport-e7acf854/description>

–>


Get-VMResourceSummary: New Download Source is Here

$
0
0

Some weeks ago, Microsoft have announced that they are going to shut down their TechNet Gallery very soon (that is: at the end of December, 2020). There is a small number of contributions that we have been involved with. Furtunately, the original license (MIT license) allows us to republish those contributions. So in the next days we are going to do this.

This contribution was first published in Microsoft’s TechNet Gallery. See the authors and copyright notices in the text below.

Hyper-V: Get RAM and vCPU assignments per VM and summed up

Overview

Hyper-V has a hard limit for the memory resources in the host server. You cannot assign more RAM to your running VMs than your host has as physical RAM.

The script Get-VMResourceSummary.ps1 lists all VMs on a host with their RAM and vCPU configurations. You get a list of each VM, its running state, static RAM assignment, maximum Dynamic Memory (if configured) and vCPU assignment.

Two summary tables inform you how much RAM and vCPUs your VMs need altogehter and how much of these core resources is assigned to the running VMs. That way you know quickly if your host’s resources allow for additional VMs or not.

Usage

The script does not use any parameters. Just launch it in a PowerShell window or in PowerShell ISE. Make sure to run PowerShell as an Administrator to get appropriate values.

The script queries the local computer by default. If you want to query a remote computer adjust the following line in the script code:

  • original: $Hostname = $env:COMPUTERNAME
  • change to: $Hostname = ‚MYSERVER‘

The script should run with Hyper-V in Windows Server 2012 and newer. It should as well run with client Hyper-V in Windows 8.1 or newer.

Download

Note: There is a file embedded within this post, please visit this post to download the file.

Author and Disclaimer

The script was written by Nils Kaczenski. It comes without any warranty or support. Use at your own risk. The project was initiated by the German IT service company Michael Wessel Informationstechnologie GmbH of Hannover.

Screenshot

clip_image001

Was <https://gallery.technet.microsoft.com/Hyper-V-Get-RAM-and-vCPU-4b29d2bb/description>

Get Circular Nested AD Groups: New Download Source is Here

$
0
0

Some weeks ago, Microsoft have announced that they are going to shut down their TechNet Gallery very soon (that is: at the end of December, 2020). There is a small number of contributions that we have been involved with. Furtunately, the original license (MIT license) allows us to republish those contributions. So in the next days we are going to do this.

This contribution was first published in Microsoft’s TechNet Gallery. See the authors and copyright notices in the text below.

Get Circular Nested AD Groups

In an Active Directory domain it is possible to have a group as a member of another group. This group nesting can be applied to multiple levels, having a group in a group in a group – and so on. Unfortunately, it is possible to create circular group nesting. This means that group nesting forms a „circle“ relationship. Imagine Group A being a member of Group B, and Group B a member of Group C. Now an administrator can put Group C into Group A as a member. Active Directory does not detect this and will not issue a warning.

Circular nesting can cause a lot of trouble, such as users that have too many permissions in applications or applications that will complain or even crash. Not mentioning the fact that circular nesting is not useful at all.

There is no simple way to detect circular nesting in an AD environment. The PowerShell script that you find for download here does the job. Simply download, verify the script, and run it. You don’t need administrator privilege to run it (unless your domain uses object-level permissions on groups).

While it would be technically possible to correct circular nesting, this is not feasible in most situations. So you can take the script’s results and resolve circular nesting manually if you find any.

Usage

  • Most simple: just run the script. It will display its results in the PowerShell window.
  • Most comfortable: Pipe the output to a grid like this:
    .\Get-CircularNestedADGroups | Out-Gridview
  • CSV automation: Automatically save the results as a CSV file like this:
    .\Get-CircularNestedADGroups | Export-CSV <FILE NAME> -Delimeter ‚;‘ -Encoding unicode -NoTypeInformation
  • HTML automation: Automatically create a simple HTML table like this:
    .\Get-CirularNestedADGroups.ps1 | Sort-Object Name | ConvertTo-Html DistinguishedName,Name,GroupScope,GroupCategory | Out-File <FILE NAME>

Download

Note: There is a file embedded within this post, please visit this post to download the file.

Disclaimer

While the script will not change anything on your system, use it at your own risk. We provide no warranty and no support.

Author

The script was written by Simon Altenbokum, michael wessel Informationstechnologie GmbH

Was <https://gallery.technet.microsoft.com/Get-Circular-Nested-AD-491145d1/description>

Bilder nicht existierender Personengruppen herunterladen

$
0
0

Schnell & schmutzig: Ich brauchte “aus Gründen” ein paar Personenbilder, die symbolisch für, naja, Personen stehen. Diese Bilder sollen keine Rechte verletzen. Also habe ich welche von der Seite “This Person Does Not Exist” genommen.

Ruft man die Seite auf, bekommt man ein Bild, das eine KI sich ausgedacht hat. Über den URL https://thispersondoesnotexist.com/image kommt man ohne HTML-Beiwerk direkt zu dem Bild.

Und so kriegt man mit der PowerShell gleich zehn davon direkt als Dateien:

for ($i = 0; $i -lt 10; $i++) {
    Invoke-WebRequest -Uri "https://thispersondoesnotexist.com/image" -OutFile "C:\Daten\Images\InexistentPerson-$i.jpg"
}

AD-Portscanner mit "Matrix-Multithreading"

$
0
0

Wir haben beruflich immer wieder mit Multi-Domain-Umgebungen zu tun, in denen User, Computer und Target Accounts (aka „zu verwaltende Konten“) in verschiedenen Domänen sind. Das bedeutet, dass wir relativ viel AD-Kommunikation brauchen. Und naturgemäß liegen dazwischen Firewalls. Daraus entstand das Bedürfnis, Ports schneller und einfacher zu prüfen also „pro Host, pro Ziel-DC und pro Port per Test-NetConnection oder portqry.exe“. Test-NetConnection ist eh ganz furchtbar langsam…

Was dabei herauskam: Ein Skript, dem du eine Liste von Zielcomputern (oder einen Domänennamen – DNS-Auflösung ist mit drin) übergeben kannst. Dann prüft es vom lokalen Computer aus alle AD-relevanten (default) oder eine benutzerdefinierte Liste von Ports gegen diese Computer. Wenn Powershell Remoting in Deiner Umgebung funktioniert, kannst du zusätzlich eine Liste von Quellcomputern angeben, von denen aus diese Ports geprüft werden sollen.

Beides läuft multithreaded. Auf dem ausführenden Rechner wird über Runspaces und PSSessions das Skript auf den Quellcomputern gestartet. Dort jeweils macht es wieder über Runspaces parallel die Port-Prüfungen.

Soweit klar? Du kannst also parallel von 4 Quellcomputern Zielports auf 4 Zielcomputern prüfen. Damit ist auch der Thread-Titel erklärt – Matrix-Multithreading

Dazu kommt noch: Das Skript kann auch die RPC-HighPorts prüfen (holt diese dynamisch vom RPC-Portmapper des Zielcomputers, Credits an Ryan Ries), es kann SSL/TLS-Ports prüfen inkl. deren Protokollversion und Zertifikat. Eignet sich also auch für Webserver-Farmen o.ä.

Wenn man’s „einfach so“ aufruft, prüft es „nur“ alle DCs der aktuellen Umgebung auf alle (naja, die meisten) AD-relevanten Ports. Dabei kommt dann z.B .so was raus:

image.thumb.png.d38221ca9e0ec4e437b68af45f4f08c7.png

Natürlich kannst du das Ergebnis auch („-PassThru“) in Powershell weiterverarbeiten statt es nur in ein Out-Gridview zu pipen  Und mit „-IncludeEPM“ bekommst du auch die RPC Highports. Oder du willst alle DCs von allen Trusting Domains prüfen – IncludeAllTrustingDomains (und vielleicht noch IncludeAllTrustedDomains?)

Interessant wird’s mit diesem Aufruf:

.\Test-TcpPorts.ps1 -Computer <ZielDom1>, <ZielDom2> -SourceComputer ( Get-ADDomain ).ReplicaDirectoryServers -IncludeEPM

Das Ergebnis (und vor allem die Ausführungszeit) mag sich jeder Interessierte gern selber mal anschauen. Die ändert sich nämlich kaum, ob es nun 5 oder 50 Server sind. Du weißt in wenigen Sekunden, welche Kommunikationswege gefiltert werden.

Hier ist der Download zu finden:

[PowerShell/Test-TcpPorts.ps1 · daabm/PowerShell · GitHub]
https://github.com/daabm/PowerShell/blob/master/Scripts/Test-TcpPorts.ps1

PS: Modulabhängigkeiten gibt es keine – intern ist alles mit AD über [DirectoryServices] gelöst. Nur das DNS-Modul brauche ich, aber das ist immer vorhanden. Und wenn Du die Zertifkate beim SSL-Check speichern willst – die Objekte dazu haben eine .Save( TargetDirectory ) Methode.

PowerShell Saturday in Hannover am 16.09.2023

$
0
0

logoNach einer längeren (Pandemie-)Pause findet am 16.09.2023 nun endlich wieder ein PowerShell Saturday in Hannover statt.
Bei dem Event wird es vor allem um PowerShell-bezogene Themen gehen, aber natürlich kommen auch andere Produkte, für die PowerShell als „Kleber“ dient, nicht zu kurz.

Die Veranstaltung findet in den Räumen der Netz-Weise statt, die viele aus den monatlichen Treffen der PowerShell User Group Hannover (PSUGH.de) kennen.
Durch die Sponsoren Netz-Weise, Script Runner und Au2Mator ist für das leibliche Wohl gesorgt.

Nähere Infos zum Event sowie die Möglichkeit; sich anzumelden, findet man auf pssat.de.

Viewing all 102 articles
Browse latest View live