SMA

Use Case – Service Management Automation – Vor Kennwortablauf warnen

Use Case – Service Management Automation – Vor Kennwortablauf warnen

Für Automatisierungen bietet Microsoft im On-Premise Bereich grundsätzlich zwei verschiedene Werkzeuge an. Zum einen ist dies der System Center Orchestrator und zum anderen Service Management Automation (SMA). Die beiden Werkzeuge verfolgen unterschiedliche Herangehensweisen was die Verwendung der Lösungen angeht. Orchestrator verfügt über ein GUI, über das man Aktivitäten per Drag-and-Drop miteinander verknüpfen kann und somit Automatisierungen ermöglicht. Service Management Automation kann sowohl per PowerShell als auch per Azure Pack Webinterface administriert werden. In der aktuellen Version ist hier keine Konfiguration per Drag-and-Drop möglich. Automatisierungen können ausschliesslich über PowerShell Workflows umgesetzt werden.

Wer in der Vergangenheit mit Orchestrator und PowerShell Aktivitäten (.NET Aktivitäten) gearbeitet hat, weiss dass man dort mit Einschränkungen und Workarounds zu kämpfen hat. Hier ist für mich die PowerShell Integration in Service Management Automation eine klare Verbesserung. Beide Werkzeuge arbeiten gut miteinander zusammen und schliessen sich nicht gegenseitig aus.

Momentan sieht es so aus, als ob Service Management Automation die Zukunft gehört. Die Zeit wird zeigen, ob beide Werkzeuge weiterhin nebeneinander existieren und welche Möglichkeiten in den nächsten Versionen von Service Management Automation hinzukommen.

Wir möchten nun anhand eines einfachen Use Cases die Funktionsweise der SMA demonstrieren:

In den meisten Active Directory Umgebungen haben Kennwörter von Benutzerkonten eine Ablauffrist. In unserem Beispiel beträgt diese 90 Tage. Nehmen wir an, dass wir Benutzer über den Ablauf der Kennwörter in bestimmten Intervallen via Mail informieren möchten. Hierfür bietet sich ein SMA Runbook an.

PowerShell Code kann in SMA Runbooks ausschliesslich über PowerShell Workflows abgebildet werden. Ein PowerShell Workflow ist die PowerShell Implementierung des WWF (Windows Workflow FrameWork). PowerShell Workflows haben einige Vorteile, aber auch einige Einschränkungen, was die Verwendung von Code angeht. So können beispielsweise .NET Code Anteile nur mittels InlineScript ausgeführt werden. Eine gute Übersicht über PowerShell Workflows bieten die beiden Technet Artikel PowerShell Workflows: The Basics  und PowerShell Workflows: Restrictions.

In diesem Beitrag gehen wir nicht näher auf die Bereitstellung der notwendigen Infrastruktur ein. Die Bereitstellung einer SMA Umgebung wird in folgendem Technet Artikel gut umschrieben Deploy Service Management Automation.

Die Erstellung und Konfiguration von Runbooks ist ziemlich geradlinig. Auf dem Service Management Portal (Web-Interface) navigiert man zu dem Punkt AUTOMATION, wo folgendes Dashboard präsentiert wird.

SMPortal

Möchte man ein neues Runbook erstellen, wählt man den Punkt NEW und anschliessend QUICK CREATE. Nun sollte man einen eindeutigen Namen vergeben, eine Beschreibung und Tags hinzufügen und mit CREATE die Erstellung abschliessen.

CreateRB

Es wird ein Runbook mit einem identisch benannten Workflow erstellt. Zu diesem Runbook gelangen wir über Klicks auf RUNBOOKS und den Namen des Runbooks. Da wir das Runbook editieren möchten, müssen wir nun auf AUTHOR und DRAFT klicken.

SMADraft

Innerhalb der geschweiften Klammern können wir unseren Code für die Automatisierung abbilden. Der Code für einen Workflow lässt sich am einfachsten mit einem PowerShell Editor wie ISE schreiben und anschliessend in SMA integrieren. Aus Gründen der Einfachheit lassen wir in unserem Beispiel erweitertes Error Handling und Logging entfallen.

Nachfolgend der komplette Code für die hier beschriebene Automatisierung:

Workflow ADPasswordRemind
{
###################################################################
#   POHN IT-Consulting GmbH
#   ActiveDirectory password expiration reminder workflow.
#   For testing purposes only.
#   Do not use in production environments
###################################################################

# Declare function for error mail messages

function SendErrorMail
{
PARAM ($ErrorText)
$Subject = "An error occurred in runbook ADPasswordReminder"
$Body = get-date + " - $ErrorText"
$To = "recipient@domain.com"
$From = "sender@domain.com"
$SMTP = "smtp.domain.com"
Send-MailMessage -From $From -SmtpServer $SMTP -To $To -Body $Body -Subject $Subject
}

# Get SMA connection object and build SMA credential object

Try
{
$Connection=Get-AutomationConnection -Name "ADRead"
$SecurePW=ConvertTo-SecureString -AsPlainText -String $Connection.Password -Force
$ADCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Connection.Username, $SecurePW
}
Catch
{
SendErrorMail "Error getting automation connection or building credential object"
}

# Get Active Directory Users via Remote-PowerShell

Try
{
$ADUsers = InlineScript {
Get-ADUser -Filter {Enabled -eq $true} -SearchBase "OU=Users,DC=domain,DC=com" -Properties UserPrincipalName,pwdLastSet | select UserPrincipalName,pwdLastSet
} -PSComputerName $Connection.ComputerName -PSCredential $ADCredential
}
Catch
{
SendErrorMail "Error getting active directory user objects"
}

# Check password expiration for each enabled user object under the given seachbase

foreach ($User in $ADusers)
{
$SendMail = "false"
$MailText = $null

Try
{
$delta = InlineScript
{
# Get delta between current date and expiration date. In this case password expiration period is 90 days.
$ExpirationDate=([datetime]::fromfiletime($Using:User.pwdLastSet));
$ExpirationDate = get-date $ExpirationDate;
$ExpirationDate = $ExpirationDate.AddDays(90);
($ExpirationDate - (get-date)).Days
}

if($delta -lt 0)
{
# Flag mail to be send every Monday if password is already expired

$MailText = "Your password is expired."
if(($today.DayOfWeek) -match "Monday")
{
$SendMail = "true"
}
}
elseif($delta -gt 0 -and $delta -lt 7)
{
# Flag mail to be send daily if passyword is about to expire within the next seven days.

$MailText = "Your password expires in $delta days."
$SendMail = "true"
}
elseif($delta -eq 14 -or $delta -eq 21)
{
# Flag mail to be send if password expires in exactly 14 or 21 days.

$MailText = "Your password expires in $delta days."
$SendMail = "true"
}
if($SendMail -eq "true")
{
# Build mail text and send mail message.

$FinalMailText = "This is an automatically generated message regarding the password expiration of your Active Directory Account.<br/>$MailText<br/><br/>Kind regards</br></br>Your IT"
Send-MailMessage -From "sender@domain.com" -SmtpServer "smtp.domain.com" -To ($Using:User.UserPrincipalName) -Body $FinalMailText -Subject "Password Expiration Warning" -BodyAsHtml
}
}
Catch
{
SendErrorMail "Error calculating expiration delta time or delivering mail to user"
}
}
}

Wir wissen bereits, dass wir Daten aus dem ActiveDirectory abfragen müssen. Eine Abfrage des ActiveDirectory kann mittels einer Connection (unter Assets im Service Management Portal) und Remote PowerShell erreicht werden. Die Konfiguration der Connections ist relativ sebsterklärend und kann folgendem Bild entnommen werden.

SMAConnection1SMAConnection2

Connections lassen sich mit Konnektoren im Orchestrator vergleichen. Der folgende Code Ausschnitt ist für die Durchführung der ActiveDirectory Abfrage notwendig:

$Connection=Get-AutomationConnection -Name "ADRead"
$SecurePW=ConvertTo-SecureString -AsPlainText -String $Connection.Password -Force
$ADCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Connection.Username, $SecurePW

Das Connection Objekt wird gelesen und ein Credential Objekt für die spätere Verwendung in der Remote PowerShell Session vorbereitet.

Die Abfrage des Active Directories wurde exemplarisch mit InlineScript und einer Connection durchgeführt. Sie ist in dieser Form und diesem Kontext technisch nicht notwendig, demonstriert aber die Verwendung von InlineScript und Connections. Für unseren Fall fragen wir die Eigenschaften UserPrincipalName und pwdLastSet ab, da in unserem Test der UPN der Mail-Adresse gleicht.

$ADUsers = InlineScript
{
Get-ADUser -Filter {Enabled -eq $true} -SearchBase "OU=Users,DC=domain,DC=com" -Properties UserPrincipalName,pwdLastSet | select UserPrincipalName,pwdLastSet
} -PSComputerName $Connection.ComputerName -PSCredential $ADCredential

Der Rest des Scriptes befasst sich mit dem Abgleich des Passwort Ablaufdatums, der Unterscheidung von verschiedenen Fällen und mit dem Versand der Mail mit Send-MailMessage.

Getestet werden sollten einzelne Code Blöcke mit einen PowerShell Editor der Wahl und anschliessend mit der Testing Funktionalität der SMA. Diese steht zur Verfügung, wenn PowerShell Code im DRAFT Bereich bearbeitet wird. Folgende Gegebenheit muss beim Testen von Runbooks beachtet werden. Die SMA Testing Funktionalität wird im Kontext des SMA Runbook Service Accounts ausgeführt. Beim Orchestrator hingegen wurde das Testing immer im Kontext des ausführenden Benutzer ausgeführt.

Nachdem das Script erfolgreich getestet wurde, muss man es im SMA noch über den Punkt PUBLISH veröffentlichen. Was nun noch fehlt ist der Auslöser für das Runbook. Hier bietet sich ein SCHEDULE an. Dies bedeutet, dass das Runbook zu einem definierten Zeiten ausgeführt wird. Ein Schedule wird über den Punkt SCHEDULE des Runbooks und ADD NEW SCHEDULE hinzugefügt.

SMASchedule2SMASchedule3

Von diesem Zeitpunkt an ist der Vorgang automatisiert und startet zur definierten Zeit. Die Abarbeitung der Jobs kann im Nachgang auf dem Dashboard nachvollzogen werden.

Wie man sehen kann, lassen sich Automatisierungen mit Service Management Automation relativ schnell umsetzten. Im Gegensatz zum Orchestrator ist man allerdings zur Verwendung von PowerShell Code gezwungen. Ein Blick auf die Produkt-Pipeline von Microsoft offenbart zusätzlich, dass man im Windows Enterprise Umfeld zukünftig an PowerShell als Administrationswerkzeug nicht mehr vorbeikommt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.