Netz-Weise Logo

Weisheiten - der Netz-Weise Blog

Hier finden Sie Tipps und Tricks für vor, während und nach der Schulung.

Geschweifte Klammern im Powershell Format-Operator benutzen am Beispiel GUIDs

Powershell hat mit dem Format-Operator -f eine geniale Möglichkeit, Texte zu formatieren. Der Format-Operator erlaubt es, Daten in einen Text zu "kopieren" und Zahlen auch gleich nach Bedarf in ein passendes Format zu bringen. Hier ein kleines Beispiel, um das Ergebnis einer Berechnung zu runden und in einen Text einzufügen:

$FolderSize = Get-Childitem -Path $env:programFiles -file -recurse | Measure-Object -Property Length -Sum
'Der Ordner {0} ist {1:0.000} MB groß' -f $env:programFiles,($Foldersize.Sum/1MB)
Der Ordner C:\Program Files ist 9169,447 MB groß

Die Syntax ist recht simpel - Sie generieren einen String, schreiben aber statt der Variablen, die in den Text eingefügt werden sollen, Platzhalter. Die Platzhalter sind durchnummeriert, beginnen bei 0 und sind in geschweifte Klammern eingefasst. Genau genommen sind die Nummern in geschweiften Klammern der Index eines Arrays, nämlich des Arrays, das Sie hinter dem Format-Operator -f angeben. {0} entspricht also dem ersten Wert hinter -f, {1} dem zweiten usw. Zahlen können Sie formatieren lassen. Geben Sie hierfür hinter dem Platzhalter einen Doppelpunkt an, und dann für jede Pflichtstellt vor dem Komma eine 0, und für jede Pflichtstelle hinter dem Komma ebenfalls eine Null. Komma wird aufgrund der amerikanischen Schreibweise mit . (Punkt) angegeben. Damit eine Zahl immer mit einer Stelle vor und drei Stellen hinter dem Komma angegeben wird, schreiben Sie also: {0:0.000}. Es gibt auch eine ganze Reihe anderer Optionen. So können Sie mit {0:C} z.B. automatisch ein Währungsformatierung (Currency) mit zwei Stellen hinter dem Komme und dem Währungssymbol der einstellten Sprache erzwingen. Eine Auflistung der Operatoren finden Sie unter https://social.technet.microsoft.com/wiki/contents/articles/7855.powershell-using-the-f-format-operator.aspx

Der Format-Operator lässt sich auch prima zum Einfügen von Zeichen verwenden, z.B. um eine Variable in Klammern oder Anführungszeichen einzufassen:

'[{0}]' -f "Ein Text in Klammern"
'"{0}"' -f "Ein Text in Anführungszeichen"

Weiterlesen
Markiert in:

Kontoinformationen über den angemeldeten Benutzer ausgeben

Sie hätten gerne Informationen über Ihre Benutzerkonto, wie Gruppenmitgliedschaften, SID usw? Wenn Sie Informationen über den gerade angemeldeten Benutzer haben möchten, wie z.B., ob der User als Gastkonto angemeldet ist, den Benutzernamen, die Domäne oder die Gruppenmitgliedschaften, hilft Ihnen die Funktion getcurrent() aus der Klasse [system.security.principal.windowsidentity] weiter.

[system.security.principal.windowsidentity]::getcurrent()

liefert folgende Properties zurück:

Name
----
Actor
AuthenticationType
BootstrapContext
Claims
DeviceClaims
Groups
ImpersonationLevel
IsAnonymous
IsAuthenticated
IsGuest
IsSystem
Label
Name
NameClaimType
Owner
RoleClaimType
Token
User
UserClaims

Eine Variante, die Ihnen entweder den Benutzer oder die Benutzermitgliedschaften zurückliefert, ist das Kommandozeilentool whoami. Mit den Parameter /User erhalten Sie Ihre SID, mit /Groups Ihre Gruppenmitgliedschaften. Alle wichtigen Informationen inklusive der Benutzerrechte spuckt der Parameter /all aus. Mit dem Parameter /Fo können Sie auch die Ausgabe im CSV-Format erzwingen, so dass Sie die Ausgabe mit Powershell direkt in Objekte konvertieren können:

Whoami.exe /groups /fo csv | ConvertFrom-CSV | Out-Gridview

Weiterlesen

Mit Powershell ein Kennwort gegen AD prüfen

Wenn Sie mit Powershell überprüfen möchten, ob eine gegebene Kombination aus einem AD-Benutzernamen und Kennwort korrekt ist (z.B. aus einer GUI-Eingabe), hilft Ihnen die .NET-Assembly System.Directore.Accountmanagement weiter (mind. .NET-Framwork 3.5). Die Klasse "PrincipalContext" enthält eine Methode ValidateCredentials, die die Überprüfung übernimmt. Die Funktion check_AdUserPassword liefert True oder False zurück und kann z.B. direkt in einem IF-Statement weiter genutzt werden.

Function Test-AdUserPassword
{

param (
    [string]
    $UserName,
    [string]
    $Password,
    [string]
    $UserDomain)

   # Lädt die Assembly "System.DirectoryServices.AccountManagement" in Powershell
   $Null = Add-Type -AssemblyName System.DirectoryServices.AccountManagement
   $ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
   $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext($ContextType, $UserDomain)
   $PrincipalContext.ValidateCredentials($UserName,$Password)

}

 

Zwei XML-Dateien mit Powershell vergleichen und einen HTML-Report erzeugen

Das XML-Format ist allgegenwärtig. Als Windows-Administrator stolpert man regelmäßig über Eventlogs im XML-Format, Anweisungsdateien für die unbeaufsichtigte Installation, Vorlagen für Gruppenrichtlinien usw. Und manchmal wäre es ganz schön, wenn man sich den Unterschied zwischen zwei ähnlichen XML-Dateien einfach anzeigen lassen könnte. Mit Powershell und ein bißchen .net ist das in der Tag auch gar kein Problem, denn Microsoft hat vor fast 15 Jahren eine .Net-Bibliothek zur Verfügung gestellt, die genau das tut - das XML Diff & Patch GUI Tool. Das Tool stellt eine Klasse zur Verfügung, über die es möglich ist, zwei XML-Dateien zu vergleichen und die Unterschiede in der XML DIfference Language (Diffgram) auszugeben. Mit einer weiteren Klasse kann man aus einer Diffgram-Datei und einer der beiden Vergleichsdateien eine HTML-Datei erzeugen, die die Unterschiede grafisch darstellt.

Wenn Sie die heruntergeladene Bibliothek entpacken, finden Sie im zwei .dlls, die Sie laden müssen, die XmlDiffPath.dll, die die Compare()-Methode zur Verfügung stellt, und die XmlDiffPath.View.dll, die die Methode GetHtml() bereitstellt. GetHtml erstellt aus einer Diffgram-Datei eine HTML-Datei. Laden Sie die Klassen und erstellen Sie zwei neue Objekte.

Add-Type -Path "xmldiffpatch.dll"
$XmlDiff = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiff
Add-Type -Path "XmlDiffPatch.View.dll"
$XmlDiffView = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiffView

Anschließend können Sie die Methode Compare() aufrufen. Compare hat eine Reihe von Überladungen (verschiedene Parameter-Kombinationen). Zum Erstellen eines Diffgramwriters benötigen Sie die beiden zu vergleichenden XML-Dateien, $false und einen .Net-Streamwriter zum Schreiben der Diffgram-Datei:

$DiffGramWriter = [System.Xml.XmlWriter]::Create( 'C:\temp\Diffgram.xml' )
#call Compare method from Microsoft.XmlDiffPatch.XmlDiff object
$XmlDiff.Compare('C:\temp\File1.xml','C:\Temp\File2.xml',$false,$DiffGramWriter)
$DiffGramWriter.Close()

Weiterlesen
Markiert in:

USB-Geräte mit Powershell und WMI auslesen

Am USB angeschlossene Geräte kann man per WMI auslesen. WMI stellt dafür die WMI Association Klasse Win32_USBControllerDevice zur Verfügung, die zwei Klassen miteinander verbindet - in diesem Fall die Daten des USB-Controllers und die installierten Treiber. Die verknüpften Treiber kann man aus der Eigenschaft Dependent auslesen.

Get-WmiObject Win32_USBControllerDevice | Foreach-Object { [Wmi]$_.Dependent }

[WMI] Wandelt den String, der in der Eigenschaft $_.Dependent hinerlegt ist, wieder eine WMI-Klasse um. Um einen überschaubaren Überblick über die installierten Geräte zu bekommen, wählt man am Besten erst einmal die Eigenschaften Descritption und DeviceID aus.

Get-WmiObject Win32_USBControllerDevice | ForEach-Object { [wmi]$_.dependent } | select-Object description,deviceid

Das Ergebnis sieht dann ungefähr so aus:

Weiterlesen

Den Windows Lizenzkey aus der Firmware aka Bios auslesen und aktivieren per Powershell

Letzte Woche habe ich durch Zufall festgestellt, dass der Rechner einer Kollegin, der schon vor Jahren per automatischem Update auf Windows 10 aktualisiert worden ist, immer noch nicht aktiviert war, obwohl das vorher installierte Windows 8.1 es war und Windows 10 sich außerdem den Key automatisch aus der Firmware ziehen soll, wenn er da hinterlegt ist. Glücklicherweise ist die Aktivierung von Windows 10 immer noch mit den Keys voriger Versionen möglich. Der Key selbst ist im BIOS nicht einsehbar, läßt sich aber über WMI einfach auslesen. Er ist in der Klasse SoftwareLicensingService in der Eigenschaft OA3xOriginalProductKey hinterlegt. Mit Powershell nutzen Sie für das Auslesen einfach Get-WMIObject oder Get-CIMClass:

(Get-WmiObject -Class SoftwareLicensingService).OA3xOriginalProductKey

oder ab Powershell 4 auch

(Get-CimInstance -ClassName SoftwareLicensingService ).OA3xOriginalProductKey

Mit dem Tool slmgr.vbs können Sie die LIzenz auch gleich installieren und aktivieren:

Weiterlesen

Kalenderdaten aus Outlook in Excel übertragen und Tage zählen

Letztes Wochenende wollte ich wissen, wie viele Tage ich im letzten Jahr geschult habe. Da alle Schulungstermine in einem Outlook-Kalender gepflegt sind, liegt es Nahe, die Termine von Outlook nach Excel zu übertragen und dann per Excel auszuwerten. Das geht tatsächlich, ist aber nicht unbedingt intuitiv.

Zuerst müssen Sie Ihren Kalender öffnen und Outlook im Menü Ansicht über den Eintrag "Ansicht ändern" in die Listenansicht umstellen. Anschließend können Sie die Ansicht über das Suchfenster filtern und die Termine, die Sie in Excel übertragen wollen, markieren und kopieren. Im Suchfenster können Sie mehrere mit Leerzeichen getrennte Wörter als einen zusammengehörigen Suchbegriff angeben, indem Sie ihn in Anführungszeichen setzen. Soll Outlook also nicht alle Termine mit Trainer oder alle Termine mit Holger im Titel finden, sondern alle des Trainers Holger, geben Sie an: "Trainer: Holger". Der Text muss dann genau so in der Terminbeschreibung eingegeben sein.

In Excel sollten sie Daten korrekt als Tabelle eingefügt werden. Sie verfügen jetzt mehrere Spalten wie Betreff, Ort, Beginn, Ende usw.

Erstellen Sie jetzt in einer neuen Spalte eine Funktion, die das Start- und Enddatum, die als Text übertragen wurden, in einen Datumswert umwndelt. Dazu benötigen Sie die Funktion Datum(), die Text in ein Datum umwandlet. Datum() hätte das Datum aber gerne im Format (Jahre;Monat;Tag), während Beginn und Ende in der Tabelle im Format "Mo 04.09.2017 09:00" vorliegen. Wir müssen aus dem Text also den Tag, den Monat und das Jahr extrahieren. Das geht mit der Funktion Teil(), die 3 Übergabewerte benötigt - Den Text oder die Zelle, die bearbeitet werden soll, das Startzeichen und die Menge der Zeichen, die augeschnitten werden sollen.Um das Jahr aus dem angegebenen Datumsformat auszuschneiden, brauchen wir die Spalte C, als Startwert 10 und 4 Zeichen:

Teil(C2,10,4)

Weiterlesen
Markiert in:

Für Powershell Cmdlet-Parameter Standardwerte definieren

Das Feature ist nicht neu, aber trotzdem noch mal eine Erinnerung wert. Wenn Sie in einem Skript für einen Parameter immer wieder das gleiche Argument verwenden, können Sie es auch als Standard-Wert hinterlegen. Konkret könnte das z.B. der Domänencontroller sein, der die Einzelbetriebsmasterrolle PDC-Emulator inne hat. Powershell stellt Ihnen dafür die Systemvariable $PSDefaultParameterValues zur Verfügung. Sie wird mit einem Hash-Array befüllt, das für jedes Cmdlet als Schlüsselwert den Cmdlet-Namen und, mit einem ":" getrennt, den Parameternamen enthält, sowie als Wert das Standard-Argument.

$Pdc = Get-ADDomainController -Service PrimaryDC -Discover
$ServerDefaults = @{ "Get-ADUser:Server"=$pdc.HostName
   "Get-ADComputer:Server"=$Pdc.HostName
   "Get-ADObject:Server"=$Pdc.Hostname
 }
$PSDefaultParameterValues = $ServerDefaults
$PSDefaultParameterValues
Get-ADUser -Filter *

Markiert in:

Eine Zahlenreihe in zwei alternierende (wechselnde) Gruppen aufteilen mit Powershell

Stellen Sie sich vor, Sie haben eine aufsteigende Reihe natürlicher (ganzer) Zahlen. Sie wollen die Zahlenreihe in 2 Blöcke aufteilen, die nach einer bestimmten Menge von Zahlen jeweils wechselt. Dazu ein Beispiel:

Gruppe 1Gruppe 2
1-500501-1000
1001-1500 1501-2000
2001-25002501-3000

 

 

 

 

Weiterlesen
Markiert in:

Ein niedrig priveligiertes Konto zum Entsperren von Domänenbenutzern anlegen und damit Benutzer-Sperren retten

Das Sperren von Benutzerkonten ist ein bewährtes Mittel, um Brute-Force-Attacken gegen Kennwörter im Unternehmen zu verhindern. Allerdings empfehlen sowohl Microsoft als auch das BSI inzwischen, Kontosperrungen nicht zu verwenden, da eine Malware oder ein Hacker durch das Sperren sämtlicher Benutzerkonten ein Netzwerk komplett lahm lagen kann - man spricht auch von einem denial of Service.

Die alternative Empfehlung lautet, lange Kennwörter in Form von Passphrases und am Besten Multifaktor-Authentifizierung einzusetzen. Grundsätzlich ist das ein vernünftiger Ansatz, aber leider scheitert er in vielen Netzwerken immer noch an der Praxis. Zum einen muß man den Benutzern erklären, dass Sie jetzt lange komplexe Kennwort-Sätze verwenden sollen, zum Anderen muß man mit dieser Variante auch für eine ordentliche Anmeldungs-Überwachung sorgen, da ein großangelegter Angriff auf die Benutzerkennwörter sonst gar nicht auffällt. Mit aktivierter Kennwortsperrung merkt man normalerweise sehr schnell, dass etwas nicht stimmt.

Mein pragmatischer alternativer Ansatz, um die Kontosperrungen weiterhin nutzen zu können, arbeitet mit automatisierten Prozessen und Powershell. Denn mit Powershell ist es sehr schnell und einfach möglich, Benutzerkonten zu entsperren. Verwenden Sie dafür die Cmdlets Search-ADAccount und Unlock-ADAccount. Search-ADAccount kann mit dem Parameter -Lockedout alle gesperrten Benutzerkonten in einem Rutsch auflisten, Unlock-ADAccount kann sie  direkt entsperren. Mit Hilfe des Cmdlets Out-Gridview können Sie sich auch gleich noch eine grafische Benutzeroberfläche einrichten, um nur ausgewählte Benutzer zu entsperren.

Search-ADAccount -Lockedout | Out-Gridview -Passthru | Unlock-ADAccount

Damit wird das Entsperren nach einem Denial of Service zu einem Kinderspiel. Allerdings muß noch ein zweites Problem gelöst werden. Wenn Sie nämlich das Standard-Administratorkonto auf der Domäne deaktivieren, haben Sie eventuell gar keine Möglichkeit mehr, die Domäne zu entsperren, weil Ihr Administrator auch gesperrt ist. Deswegen legen Sie sich nun ein niedrig privilegiertes Konto an, dass neben dem Entsperren von Benutzern in der Domäne nichts kann, aber nicht gesperrt wird.

Weiterlesen