AD User Query and Selecting

Für einen regelmässigen Export aus dem Active Directory habe ich mich entschlossen das bestehende VBScript durch ein, von Grund auf neu geschriebenes, Powershell Script zu ersetzten. Active Directory Abfragen, welche früher in VBScript mit AdoDB und dem ADSI Interface gemacht wurden können mit Powershell bequem über die entsprechenden Cmdlets realisiert werden. Dabei gibt es ein paar Unterschiede zwischen dem ADSI Interface und dem Active Directory Web Services, welches von den Powershell Cmdlets genutzt wird, zu berücksichtigen. Ein Beispiel ist der Security Identifier (SID) welcher von ADSI Binär und von AD Web Services als String Repräsentation geliefert wird. Genau dieser wurde in oben erwähntem Export explizit in Binär Form gewünscht, wofür ich eine Konvertierung in das Powershell Script einbauen musste. Falls noch weitere solche Anforderungen auftauchen habe ich ein wieder verwendbares Snippet erstellt was mir ermöglicht auf allen Attributen der Abfrage Modifikationen durchzuführen. Das sieht folgendermassen aus

[object[]]$Attributes = 
"sAMAccountName",
"givenName",
"sn",
"Title",
"Department",
"Company",
@{L="objectSid";E={
  $buf = [Byte[]]::new($_.objectSid.BinaryLength)
  $_.objectSid.GetBinaryForm($buf,0)
  ([System.BitConverter]::ToString($buf)).Replace("-","")
}}

$Properties = ($Attributes | ForEach-Object { @($_, $_.L)[$_.L -ne $null] })
Get-ADUser -LdapFilter "(cn=pri)" -Properties $Properties | Select-Object $Attributes | Format-Table -AutoSize

In Zeile 1-12 wird ein Array aus Objekten erstellt, welches entweder nur den Attribut Namen als String enthält, wenn keine Modifikationen durchgeführt werden sollen oder eine Hashtable mit den Keys L (Label) und E (Expression) welche als Input für das Cmdlet Select-Object verwendet werden kann. Zeile 14 bildet ein String Array welches als Parameter für das -Properties Attribut der RSAT-AD Cmdlets verwendet werden kann.

Das Resultat sieht folgendermassen (hier als Tabelle formatiert) aus.

Powershell Ternary Operator

Ich finden den Ternary Operator (Vereinfachung einer if-then-else Anweisung auf einer Zeile) sehr praktisch. Er ist leserlicher als eine simple if-then-else Anweisung, welche sich über mehrere Zeilen verteilt. Viele Sprachen haben den Ternary Operator eingebaut. Nachfolgend ein Beispiel, wenn die Variable “threshold” grösser als 80 ist wird der String “critical”, ansonsten “normal” ausgegeben.

# Konstruktion
value_if_true if condition else value_if_false

# Beispiel
threshold = 79
print('critical' if threshold > 80 else 'normal')
# >> normal
// Konstruktion
condition ? value_if_true : value_if_false

// Beispiel
#include <stdio.h>

int main() {
    int threshold = 81;
    printf("%s", threshold > 80 ? "critical" : "normal");
}
// >> critical

Obschon es den Ternary Operator für Powershell nicht gibt kann sein Verhalten “nachgebaut” werden. Dafür kann die Tatsache, dass ein boolscher Wert durch eine 0 oder eine 1 repräsentiert wird in Zusammenhang mit einem Array verwendet werden. Je nach Script / Programmiersprache ist es unterschiedlich wie ein Wahr oder ein Falsch intern abgespeichert wird. Für Powershell finden wir das mit folgendem Code heraus.

[int]$true
# >> 1
[int]$false
# >> 0

Daraus ist ersichtlich, dass im Array Index 0 der Falsch Wert stehen muss und im Index 1 der Wahr Wert. Das oben verwendete Beispiel sieht dann folgendermassen aus.

# Konstruktion
array(value_if_false,value_if_true)[condition]

# Beispiel
[int]$threshold = 79
Write-Host @('normal','critical')[$threshold -gt 80]
# >> normal

Wofür das Ganze sinnvoll eingesetzt werden kann ist der Kreativität überlassen. In einem noch folgenden Beitrag werde ich aufzeigen wofür ich es bereits verwendet habe.