Weisheiten - der Netz-Weise Blog

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

Powershell Ausgabeströme verstehen und umleiten

"Ein Überblick darüber, wie Powershell Daten ausgibt, und wie sie dieses Verhalten steuern können. Wenn Sie in Powershell Daten an der Konsole ausgeben wollen, stehen Ihnen eine ganze Reihe von Commandlets zur Verfügung. Die wichtigsten sind:

  • Write-Output
  • Write-Error
  • Write-Warning
  • Write-Verbose
  • Write-Debug

Außerdem gibt es noch das gerne genutzte, aber leider böse Write-Host. Warum Write-Host böse ist, werden Sie gleich verstehen. Die 5 vorgestellten Commandlets haben alle eigene ""Ausgabeströme"" oder Kanäle, in denen die Daten ausgegeben werden. Man kann sich das vorstellen wie 5 parallele Straßen, auf denen der Verkehr geregelt wird. Die Linke Spur ist für LKW vorgesehen, die 2. Spur für Busse, die 3. für Taxen, die 4. für normalen Personenverkehr und die 5. für Einsatzfahrzeugt. Normalerweise sind die Spuren komplett voneinander getrennt, kommen sich also nicht in Gehege. Der normale Ausgabestrom wird auch von der Pipeline genutzt. Daten, die mit Write-Output in den Ausgabestrom geschrieben werden, landen in der Pipeline und können dort weiterverarbeitet werden. Alle anderen Ausgaben (Fehler, Debugmeldungen usw.) landen nicht in der Pipeline, da die Pipeline nur am Standard-Ausgabestrom hängt. Dadurch können alle in der Pipeline nicht benötigten Daten aus Ihr heraus gehalten werden. Genau wie auf einer Straße die Spuren gewechselt werden können, kann man in der Powershell auch Daten umleiten. Dafür gibt es den Umleitungsoperator >&. Vor dem > steht der Strom, der umgeleitet werden soll, hinter dem & steht der Strom, auf den umgeleitet werden soll. Die Ströme sind eindeutig durchnummeriert: 1 Output 2 Error 3 Warning 4 Verbose 5 Debug Das Kommando

$VerboseMessage = Write-Verbose -message "Dies ist eine Ausgabe" -verbose 4>&1

schreibt die Ausgabe des Write-Verbose-Befehls in eine Variable. Geben Sie nur

$VerboseMessage = Write-Verbose -message "Dies ist eine Ausgabe" -verbose

ohne den Umleitungsoperator an, wird die Nachricht ausgegeben, aber nicht in der Variablen gespeichert. (Der Parameter -verbose ist übrigens dafür da, ausführliche Nachrichten überhaupt erst auszugeben. Write-Verbose Ausgaben werden nur angezeigt, wenn die Variable $VerbosePreference auf Stop, Inquire oder Continue gesetzt ist, oder im Commandlet explizit der Parameter -verbose gesetzt wurde.) Das die Ausgabe nur mit dem Zuweisungsoperator 4>&1 gespeichert wird, liegt daran, dass in Variablen immer nur der Standard-Ausgabestrom gespeichert wird. Dadurch werde Fehlermeldungen usw. aus den Variablen heraus gehalten. Wollen Sie alle Ausgaben in eine Datei speichern, so hilft Ihnen die Umleitung *> c:\outputfile.txt Diese Ausgabe leitet sämtliche Ausagen in die Zieldatei um. Aber dummerweise nicht die Ausgaben, die write-host generiert. Write-Host nutzt nämlich keinen der Ausgabeströme, sondern schreibt direkt in die Konsole. Dadurch geht sämliche Kontrolle über die Ausgabe verloren. Nutzen Sie daher am Besten, soweit möglich, immer write-output für Ihre Ausgaben. "

Bitlocker mit FDE (Verschlüsselung in Hardware) nutzen

*Update*: Microsoft unterstützt die Verschlüsselung in Hardware seit Windows 10 1903 nicht mehr, da es zu häufig Probleme mit der Implementierung der Hersteller gab.

"So verschlüsseln Sie Ihre Festplatte performant, aber zentral verwaltet Seit Windows 8 unterstützt Bitlocker die Möglichkeit, direkt die Hardwareverschlüsselung der Festplatte zu nutzen. Diese Technik wird von Microsoft als edrive bezeichnet. Dadurch, dass Bitlocker die Daten nicht mehr verschlüsseln muß, bevor er sie auf der Festplatte speichert, bekommt man die Verschlüsselung quasi komplett ohne Performance-Einbußen. Im Gegensatz zur reinen FDE-Verschlüsselung (Full Drive Encryption), also der Verschlüsselung direkt durch die Festplatte ohne Bitlocker, kann man die Verschlüsselung aber zentral administrieren. Leider ist das Feature mal wieder bescheiden dokumentiert. Daher habe hier nach einer langen Leidens- bzw. Experimentierphase mal alle Erkenntnisse zusammengetragen. Um Bitlocker mit FDE nutzen zu können, benötigt man zum einen eine Festplatte (SSD), die FDE unterstützt und OPAL 2.0 kompatibel ist. Zwei Modelle, von denen ich das definitv weiß, sind die Crucial M500 und Nachfolgemodelle, sowie die Samsung Evo 840. Zum anderen muß der Computer bereits über UEFI-Bios (ab UEFI 2.3.1) verfügen und UEFI muß aktiviert sein. Der Secure Boot Mode darf laut Crucial nicht aktiviert sein! Um die Hardware-Verschlüsselung nutzen zu können, muß Windows im UEFI-Modus installiert werden. Das passiert automatisch, wenn das BIOS auf UEFI-Boot gesetzt ist. Eine große Stolperfalle: Die Festplatte muß leer und blank sein, wenn Windows die Installation startet. Dafür reicht es NICHT aus, die Partitionen auf der Festplatte im Installationsmenü zu löschen - das habe ich auf dem harten Weg gelernt. Löschen Sie stattdessen die Festplatte mit Diskpart, falls die Platte bereits initialisiert war. Dazu können Sie im Installationsmenü von Windows 8 die Tastenkombination shift-F10 drücken. Dann öffnet sich ein Kommandozeilenfenster. Geben Sie folgende Befehlskombination ein:

List Disk 
-> Finden Sie aus der List Ihre SSD
Select Disk
-> Geben Sie die Nummer Ihrer Festplatte an
Clean
-> löscht die Festplatte ratzekahl leer

Achtung! Clean heißt, dass die Festplatte komplett komplett gelöscht wird. Die Partitionen genauso wie die Partitionstabellen werden entfernt. Kontrollieren Sie also 3 mal, ob sie den richtigen Datenträger ausgewählt haben. Nun können Sie Windows 8 installieren. Nach der Installation können Sie Bitlocker installieren. Wenn Sie kein TPM (Trusted Platform Module) in Ihrem PC haben, müssen Sie Windows explizit erlauben, die Verschlüsselung mit USB-Datenträger oder Kennwort zu sichern. Starten Sie hierfür GPEdit.msc und öffnen Sie ""Computerkonfiguration -> Administrative Vorlagen -> Windows Komponenten -> Bitlocker Laufwerksverschlüsselung -> Betriebssystemlaufwerke -> Zusätzliche Authentifizierung beim Start anfordern"" und setzen sie den Radiobutton bei aktiviert. Anschliessend klicken Sie auf OK. Um sicher zu gehen, dass Sie wirklich die Hardwareverschlüsselung nutzen, verwenden Sie zur Aktivierung am Besten die Powershell. Starten Sie dafür ein Windows Powershell-Fenster mit Administrativen Rechten und starten Sie folgenden Befehl:

$password = ConvertTo-SecureString -String "Passwort" -AsPlainText -Force
Enable-BitLocker -MountPoint "C:" -HardwareEncryption -PasswordProtector -Password $Password

Wobei Mountpoint dem Laufwerk entspricht, dass Sie verschlüsseln wollen. Gibt es ein Problem mit Ihrer Konfiguration, meldet der Befehl, dass eine Hardwareverschlüsselung nicht möglich ist. Um Bitlocker per GUI zu aktivieren, starten Sie die Systemsteuerung, wählen ""Bitlocker Laufwerkverschlüsselung"" und dann aktivieren für das zu verschlüsselnde Laufwerk. Geben Sie ein Kennwort ein und wählen Sie, wo Sie den Wiederherstellungsschlüssel speichern wollen (Achtung! Wenn Sie den Wiederherstellungsschlüssel verlieren und Ihr Kennwort vergessen, kann bestenfalls der NSA noch Ihre Daten wiederherstellen, wobei selbst das eher unwahrscheinlich ist!). Danach wird eine Systemüberprüfung durchgeführt. Wenn Ihnen Bitlocker da"

VHD-Dateien beim Windows-Start automatisch mounten

"So mounten Sie eine VHD oder VHDX-Datei beim Systemstart von Windows automatisch Windows kann seit Vista virtuelle Festplatten wie normale Datenträger bereit stellen. Um das zu bewerkstelligen, können Sie in die Computerverwaltung -> Datenspeicher -> Datenträgerverwaltung gehen, das Kontextmenü der Datenträgerverwaltung öffnen und auswählen "virtuelle Festplatte anfügen". Alternativ können Sie auch das Powershell-Commandlet Mount-VHD verwenden:

mount-vhd -path C:\vhd\daten.vhdx 

Leider ist der Datenträger nur so lange eingehängt, bis der Computer neu gestartet wird. Wenn Sie die virtuelle Festplatte aber gerne bei jedem Systemstart verfügbar hätten, müssen Sie tricksen. Variante 1: Nutzen Sie das Tool vhd attach. VHD Attach stellt eine grafische Oberfläche für die Verwaltung von VHD-Dateien zur Verfügung, installiert aber auch einen Dienst, der beim Systemstart eine vhd-Datei einhängen kann. Dafür starten Sie VHD Attach, mounten die Festplatte, die sie benötigen, und klicken dann im Menü auf ""Auto-Mounted"". Variante 2: Wenn Sie mehrere Maschinen mit einem Auto-Mount einrichten oder ohne Installation auskommen wollen, hilft Ihnen der Task-Scheduler weiter (Aufgabenplanung im Deutschen). Hier können Sie eine Aufgabe anlegen, die beim Systemstart ausgeführt wird und ein Powershell-Script mit mount-vhd startet. Und als kleine Fingerübung machen wird das gleich mit Powershell und einem geplanten Task. (Mehr zu geschedulten Tasks und Jobs in meinem nächsten Tipp).

$user = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username,$Password 
$action = $jobtrigger = New-JobTrigger -AtStartup
New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-noprofile -command mount-vhd -Path 'C:\vhd\daten.vhdx'"
Register-ScheduledTask -TaskName Mount_VHD -Trigger $jobtrigger -Action $action -User "system" -RunLevel Highest

Der Jobtrigger -AtStartup legt fest, dass der Task beim Systemstart ausgeführt werden soll. Mit Register-ScheduledTask wird die Aufgabe im Taskplaner registriert. Die Action ist der Powershell-Aufruf, der das Befehl "Mount-VHD" startet. Erwähnenswert ist noch, dass der Task als Benutzer "System" gestartet wird und damit automatisch administrative Rechte hat. Um den Task als System zu starten, benötigt man allerdings administrative Berechtigungen.

Bitlocker-Laufwerke wiederherstellen ohne Recovery-Key

Wenn Ihr Rechner mit einer Bitlocker verschlüsselten Festplatte arbeitet und aufgrund eines Bootproblems nicht mehr startet, benötigen Sie den Recovery-Key - oder diesen Artikel. Wenn Ihr Rechner mit einer Bitlocker verschlüsselten Startpartition arbeitet, kann es schon mal passieren, dass der Rechner nach einem Absturz nicht mehr starten will. Dann benötigen Sie, um aus den Reparaturoptionen auf das Laufwerk zugreifen zu können, den Recovery-Key, der beim erstellen des Laufwerks erzeugt wurde. Oder Sie starten eine Kommandozeile und entschlüsseln die Platte mithilfe des Kommandozeilentools manage-bde.exe. manage-bde kann die Festplatte von der Kommandozeile aus mit der Recovery-Key-Datei, dem Recovery-Kennwort (ein ellenlanger Zahlenschlüssel) oder mit dem Kennwort entschlüsseln, mit dem Sie die Platte verschlüsselt haben. Starten Sie hierzu Ihren Rechner, geben Sie Ihr Kennwort ein, und warten Sie, bis Windows Sie ihnen sagt, dass der Rechner nicht gestartet werden kann. Wählen Sie dann Reparieren oder Problembehandlung und dann erweiterte Optionen. Anschliessend wählen Sie "Eingabeaufforderung aus.  Der Rechner startet nun neu. Melden Sie sich an und geben Sie in der sich öffnenden Kommandozeile folgenden Befehl ein, wobei Sie C: durch den Laufwerksbuchstaben ihres verschlüsselten Laufwerks ersetzen: 

manage-bde -unlock c: -password "Ihr Kennwort"
manage-bde -off C:

Das Laufwerk wir jetzt entschlüsselt und Bitlocker deaktiviert. Anschließend können Sie Ihren Rechner wieder im Reparaturmodus starten. An dieser Stelle empfiehlt es sich, eventuell schnell noch ein Backup Ihrer Daten zu machen. Anschliessend können eventuell folgende Befehle Ihren Rechner wieder flott machen: 

chkdsk C: /V /F
bootrec /fixboot
bootrec /RebuildBcd

Übrigens ist es für dieses Vorgehen notwendig, den Rechner wirklich über den Reparaturmodus zu starten, nicht über einen PE-Stick. Ansonsten könnte Sie beim aufrufen von manage-bde folgende Fehlermeldung begrüßen:

ERROR: An error occurred <code 0x80070057>
The parameter is incorrect

Hyper-V VM startet nicht mit Fehler "weil der Hypervisor nicht ausgeführt wird"

Ihre Hyper-V virtuellen Maschinen melden "Der virtuelle Computer konnte nicht gestartet werden, da der Hypervisor nicht ausgeführt wird" Dieses Problem kann auftreten, wenn die Virtualisierungsfunktionen im BIOS nicht freigeschaltet sind. Das kann man z.B. mit dem Sysinternals-Tool "Coreinfo" aus der Sysinternals-Suite testen. Eine weitere Ursache kann sein, dass der Hypervisor-Eintrag im Boot-Menü fehlt, z.B. nach einer Reparatur des Bootmenüs, oder wenn Sie von einer vhd aus Ihr Windows starten. Dann hilft folgender Aufruf in einer vom Administrator gestarteten Kommandozeile (rechte Maustaste auf cmd.exe und "Ausführen als Administrator):

bcdedit /set hypervisorlaunchtype Auto

Get-content und der RAW-Switch

"Mit Powershell 3.0 wurde der Get-Content-Befehl um einen Switch-Parameter erweitert, um Inhalte in einen einzigen String einzulesen statt zeilenweiseDer Get-Content-Befehl liest Textdateien normalerweise Zeilenweise ein. Der Inhalt einer Textdatei wird damit in ein Array eingelesen, wobei jede Zeile in einer einzelnen String-Variablen gespeichert wird. Das ist allerdings nicht nur langwierig, sondern oft auch nicht erwünscht. Mit dem -RAW Switch ignoriert get-content Newline-Zeichen und liest den Dateiinhalt in einen einzigen String ein. Das geht deutlich schneller, wenn man nicht auf die einzelnen Zeilen zugreifen möchte, sondern den Dateiinhalt braucht, wie er ist. Wenn es um sehr große Dateien geht, erweist sich die .net-Klasse [io.file] als noch deutlich schneller: $file = [io.file]::ReadAllLines('C:\temp\WindowsUpdate.log')"

Werte und Arrays aus Funktionen zurück liefern

Eine Funktion bei Powershell ist eigentlich nur ein benannter Scriptblock. Funktionen kann man nutzen, um Scripte übersichtlicher zu gestalten und bestimmte Funktionalitäten immer wieder aufrufbar in einen Block zu "giessen". Wenn Sie eine Funktion schreiben, soll diese fast immer auch Werte zurück liefern, mit denen Sie weiterarbeiten können. In vielen anderen Programmiersprachen verwendet man hierzu das Return-Statement. Powershell kann das grundsätzlich auch, allerdings ist das Return-Statement nicht wirklich notwendig, um Rückgaben zu erzeugen, da grundsätzlich jede Ausgabe von einer Funktion ausgegeben wird. Hierzu ein kleines Beispiel:

function Return-Value
{
    1
    Return 2
}
$Rueckgabe = Return-Value

Was befindet sich jetzt in der Variable $Rueckgabe? Nicht der Wert 2, wie man vermuten könnte, sondern $Rueckgabe ist ein Array, dass die Werte 1 und 2 enthält. Ein weiteres Beispiel:

function Return-Value
{
    1
    2 "Schoene Gruesse von Return-Value"
}
$Rueckgabe = Return-Value

$Rueckgabe ist wieder ein Array, das 3 Werte enthält, und das auch ohne Return. Return ist zur Rückgabe von Werten also nicht notwendig. Wofür benötigt man dann noch Return? Return beendet außerdem die Funktion. Befehle, die nach Return stehen, werden also nicht ausgeführt! Wenn Sie Arrays aus einer Funktion zurück liefern wollen, müssen Sie vorsichtig sein! Möchten Sie beispielsweise 2 Arrays zurückgeben, so fügt Powershell diese in der Rückgabe zu einem Array zusammen:&nb

function Return-Value 
{
$arr1 = 1,2,3,4
$arr2 = 5,6,7
$arr1
$arr2
}
$Rueckgabe = Return-Value

Rueckgabe enhält wiederum ein Array mit den Werten 1 bis 7. Geben Sie $Rueckgabe[0] an, so erhalten Sie aber nicht das erste Array, sondern nur den Werte 1. Um Powershell anzuweisen, die Arrays beizubehalten, müssen Sie der Ausgabe ein Komma voran stellen:

function Return-Value 
{
$arr1 = 1,2,3,4
$arr2 = 5,6,7
$arr1,$arr2
}
$Rueckgabe = Return-Value

Dann gibt $Rueckgabe[0] auch die Werte 1 bis 4 zurück.

Parametrisierte Programme in Powershell starten am Beispiel von 7Zip

Wenn man in Powershell ein ausführbares Programm starten möchte, kann man das normalerweise machen, indem man den direkten Pfad in der in der Konsole einfach aufruft. Genauso kann man ein Programm in einem Script direkt referenzieren.

C:\programme\7zip\7z.exe

Problematischer wird das, wenn der Pfad, in dem sich das Programm befindet, Leerzeichen enthält. Der Programmpfad muß dann in Anführungszeichen gesetzt werden, wird nun aber als String interpretiert und kann nicht mehr direkt aufgerufen. Powershell gibt stattdessen einfach nur den String zurück.

'C:\Program Files\7Zip\7z.exe'
C:\Program Files\7Zip\7z.exe

Die Lösung bietet der Ausführungsoperator &, der Powershell anweist, den folgenden String direkt auszuführen:

Weiterlesen

Gültigkeitsbereiche von Variablen und der Modul-Scope in Powershell

Vor kurzem bin ich auf einen interessanten Artikel von Mike Robbins gestoßen, den ich hier noch einmal kurz zusammengefasst wiedergeben möcht.

Variablen haben in Powershell normalerweise nur eine begrenzten Lebensdauer, die vom Scriptblock definiert ist, in dem Sie deklariert wurde. Sobald der Scriptblock beendet wird, in dem eine Variable deklariert wurde, wird auch die Variable wieder freigegeben. Hierzu ein kleine Beispiel:

$TestVariable = 'Hallo vom Script'
function Test-Scope
{
  $TestVariable = 'Hallo aus der Funktion'
  $TestVariable
}
Test-Scope
$Testvariable

Wie sieht die Ausgabe des Skripts aus und was ist der Inhalt der Testvariablen zu den unterschiedlichen Zeitpunkten?

Das Skript gibt diese Ausgabe zurück:

Weiterlesen

Emails mit Skripten oder Multifunktionsgeräten über Office 365 versenden

Wenn Sie mit "Fremdapplikationen" wie Multifunkitionsdruckern oder aus einem Skript Mails über die Microsoft-eigenen Office 365 Exchange-Server versenden wollen, haben Sie grundsätzlich drei Möglichkeiten: Den anonymen Mailversand, den Versand über ein authentifiziertes Benutzerkonto oder einen dezidierten Connector. In dieser Beschreibung möchte ich mich auf die ersten zwei, weil vermutlich häufigesten, konzentrieren. Den vollständigen Artikel von Microsoft zur Einrichtung aller drei Methoden inklusive des Connectors finden Sie unter "Links" am Ende des Textes.

Die einfachste Variante, um mails zu verschicken, ist ein Postfach in Office 365 anzulegen, also einen neuen Benutzer. Danach können Sie sowohl interne mails (also innerhalb Ihrer O365-Organisation) als auch externe Mails verschicken. Sie verwenden für den Mailversand den Server smtp.office365.com und müssen eine Anmeldung mit Benutzername und Kennwort des Postfachbenutzers durchführen. Hier ein kleines Beispiel mit Powershell:

$Password = Convertto-Securestring -String 'Passwort' -AsPlainText -Force
$credential = New-Object PSCredential("Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!",$Password)
Send-MailMessage -SmtpServer smtp.office365.com -Port 587 -UseSsl -Subject 'Ein Fehler ist aufgetreten' -Body 'fehler' -from Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!' -To Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!' -Credential $credential

Alternativ kann für den Versand auch Port 25 verwendet werden, bevorzugt ist aber Port 587, der für TLS-Verschlüsselung verwendet wird.

Der Nachteil dieser Variante ist, dass Sie ein Postfach und damit eine Benutzerlizenz benötigen. Außerdem ist die Menge der mails, die pro Minute verschickt werden können, auf 30 eingeschränkt. Alternativ können Sie aber auch direkt versenden, ohne eine Postfach zu verwenden. Diese Variante funktioniert aber nur für internen Mailversand - Office 365 leitet keine Mails an Benutzer außerhalb Ihrer Organisation weiter.

Markiert in:
Weiterlesen

Parameter in Powershell-Funktionen und Skripten vor Intellisense verstecken

Der Scriptblock in Powershell stellt standardmäßig einen Param-Block zur Verfügung, über den Parameter an Skripte und Funktionen übergeben werden können. Erweiterte Funktionen bieten darüber hinaus einen ganze Reihe von Parameter-Optionen, um das Verhalten der Parameter steuern zu können. Eine manchmal sehr hilfreiche, unbekannte Parameter-Option ist DontShow, mit der man verhindern kann, dass ein Parameter in Intellisense angezeigt wird.Das kann z.B. nütlich sein, wenn man Hilfsfunktionen baut, die allgemein nutzbar (öffentlich) sind, bei denen bestimmte Hilfsparameter aber nur unter ganz bestimmten Spezialfällen sinnvoll sind. Geben Sie bei den Parameter-Optionen einfach DontShow mit an:

function Test-HiddenParam
{
Param(
   [Parameter(DontShow)]
   [string]$hiddenParameter
)

$hiddenParameter
}

 

Send-Mailmessage erzeugt keine verwendbaren Fehler - und wie man damit umgeht

Send-Mailmessage ist ein sehr nützliches Cmdlet, um Emails direkt aus Powershell an einen Mailserver zu senden. Er steht seit Powershell 2.0 zur Verfügung und vermeidet so, dass man sich direkt mit dem [System.net.mail]-Typ herumschlagen muß. Allerdings zeigt das Cmdlet ein sehr merkwürdiges Fehlerverhalten.

Wenn man versucht, Verbindungsfehler abzufangen, ist ein erster vernünftiger Ansatz, einfach auf den Parameter -Errorvariable zurückzugreifen:

Send-Mailmessage -SmtpServer mail.meineFirma.de -Subject 'Warnung' -Body 'Hier kommt die Maus' -From Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!' -to Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!' -ErrorVariable Fehlermeldung
If ( $Fehlermeldung ) { $Fehlermeldung.Exception.Message }

Tritt ein Fehler auf, wird dieser direkt in der Variablen $Fehlermeldung gespeichert. Achtung, bei der Angabe der Fehlervariablen wird kein $-Zeichen angegeben!

Dummerweise funktioniert diese Herangehensweise nicht. Die Variable $Fehlermeldung bleibt immer leer. Also nächster Versuch, Abfragen der Variablen $Error[0], die alle Fehler als Array speichert und im ersten Eintrag mit dem Index 0 immer den letzten Fehler gespeichert hat. Um herauszufinden, ob Send-Mailmessage einen Fehler geworfen hat oder erfolgreich war, kann man über die Standardvariable $? abrufen. $? ist true, wenn der letzte Befehl erfolgreich war, und false, wenn ein Fehler aufgetreten ist.

Markiert in:
Weiterlesen

MDT - Autologon nach Installation aktiviert lassen

In letzter Zeit beschäftige ich mich wieder intensiv mit dem MDT, um unsere Schulungs-Rechner mit neuen Windows 10 Images zu versehen. Dafür habe ich ein kleine Powershell-Funktion geschrieben, den den Autologon für einen Benutzer setzt (s.u.). Sie kann den Autologon aktivieren. Leider funktioniert die Funktion nicht innerhalb eines Konfigurationsskriptes im MDT, da nach erfolgter Installation das Aufräumskript Scripts\LTICleanup.wsf den Autologon entfernt. Um den Autologon beizubehalten oder ändern zu können, suchen Sie den Text

     '//----------------------------------------------------------------------------
     '//  Clear the autologon registry keys
     '//----------------------------------------------------------------------------

und kommentieren Sie die nachfolgenden Zeilen bis zum nächsten Kommentarblock mit dem ' aus.

function Set-AutomaticLogon
{
<#
.Synopsis
    Enables Windows Autologon or removes it
.DESCRIPTION
    This function enables Windows Autologon via Registry-Keys or disables it. It is similar
    to the Netplwiz.exe Command
.EXAMPLE
    Set-AutomaticLogon -Enabled -Username Student -Password Password
    Adds an Autologon-Key to the Registry.
.EXAMPLE
    Set-AutomaticLogon -Disabled
    Disables the automatic Logon by removing the User-Password and disabling the Logon-key.
#>
param
(
    [parameter(Mandatory=$True,
               ParameterSetName='Enabled')]
    [switch]$Enabled,

    [parameter(Mandatory=$True,
               ParameterSetName='Disabled')]
    [Switch]$Disabled,

Weiterlesen

MDT: Sysprep und Catpure zeigt das Register "Capture Image" nicht an und der Task schlägt fehl

Das Microsoft Deyployment Toolkit 2013 hat in der aktuellen Version 8443 einen Bug, der die Tasksequenz "Sysprep and Capture" funtionsunfähig macht. Leider hat Microsoft den Bug bisher nicht durch eine aktualisierte Version bereinigt. Man kann sich aber schnell selbst behelfen, denn es handelt sich um fehlerhaften VBS-Code in der Datei ZTIUtility.vbs im Ordner Scripts im Root des Deployment-Shares. Ersetzen Sie in Zeile 3327 den Code 

If (oTS.SelectSingleNode("//step[@type='BDD_InstallOS']") is nothing) and (oTS.SelectSingleNode("//step[@type='BDD_UpgradeOS']") is nothing) then

durch

if (oTS.SelectSingleNode("//step[@type='BDD_InstallOS' and @disable='false']") is nothing) and (oTS.SelectSingleNode("//step[@type='BDD_UpgradeOS' and @disable='false']") is nothing) then

Danach sollte die Tasksequenz problemlos durchlaufen.

Links
https://community.spiceworks.com/topic/1924854-mdt-8443-sysprep-capture-task-not-working

Sichere Kennwörter in Powershell generieren, jetzt mit dem .NET Framework

In meinem Blogeintrag Zufällige (Komplexe) Kennwörter erzeugen mit Powershell vom 23.04 habe ich gezeigt, wie man komplexe Kennwörter mit Powershell generieren kann, indem man zufällige Zeichen mit Get-Random erzeugt. Aber es geht auch einfacher, denn das .NET-Framework bietet bereits eine fertige statische Methode zum generieren von Kennwörtern, die man in Powershell nur noch laden muß. Die Methode heißt GeneratePassword und befindet sich in der [System.Web]-Assembly. Die Assembly ist in Powershell allerdings nicht standardmäßig geladen. Dies kann man mit dem Cmdlet Add-Type erledigen: 

Add-Type -AssemblyName System.web

Nun können Sie die Methode GeneratePassword aus der Klasse [System.Web.Security.Membership] aufrufen. Der Aufruf erfolgt über [Klasse]::Methodenname(Parameter):

[System.Web.Security.Membership]::GeneratePassword(10,3)

Die beiden Parameter 10 und 3 bestimmen die Anzahl der Zeichen sowie die nicht-Alphanumerischen Zeichen, die das Kennwort enthalten muß. 

Markiert in:
Weiterlesen

Inaktive Benutzer oder Computer mit Powershell finden und deaktivieren

Das Cmdlet Search-ADAccount ist das Schweizer Messer des AD-Administrators. Es zeigt gesperrte Konten genauso an wie deaktiviert Konten, ablaufende Konten und Konten, deren Kennwort niemals abläuft. Der vielleicht hilfreichste Parameter ist aber -AccountInactive, der Konten anzeigt, die sich schon lange nicht mehr in der Domäne angemeldet haben. Grundsätzlich kann man dieses auch mit Get-ADUser und Get-ADComputer lösen, aber das ist aufwändiger und außerdem muß man auch darauf achten, welches AD-Attribut man auswertet, denn es gibt mehrere Eigenschaften, die die letzte Anmeldung speichern, aber nicht alle sind gleich gut geeignet. Eine gute Auflistung der Attribute und deren Unterschiede finden Sie im Technet-Wiki

Um inaktive Konten anzuzeigen, nutzen Sie einfach

Search-ADAccount -AccountInactive

Der Parameter findet sowohl Benutzer- als auch Computerkonten, die sich seit 60 Tagen nicht mehr angemeldet haben. Wenn Sie nur Benutzer suchen, verwenden Sie den Parameter -Usersonly, wenn Sie die Zeitspanne angeben wollen, benutzen Sie den Parameter Timespan, gefolgt von den Tagen seit dem letzten Login:

Search-ADAccount -AccountInactive -TimeSpan 90 -UsersOnly

Weiterlesen

Einen Secure String oder ein PSCredential-Objekt wieder in ein Klartextkennwort umwandeln

In Powershell ist es oft  notwendig, einen Secure-String zu erzeugen. SecureStrings werden z.B. zum Erstellen eines AD-Benutzers verwendet, oder für alle möglichen Arten von Anmeldeinformationen. Das Geheimnis eines SecureStrings besteht darin, dass er über die Microsoft DPAPI (Data Protection API) durch das Konto des Benutzers geschützt ist, der den SecureString erzeugt hat. Dadurch kann nur er auf das Kennwort des SecureStrings zugreifen. 

Manchmal gibt es aber die Situation, in der man das Kennwort eines Securestrings gerne wieder im Klartext hätte. Als Beispiel dafür soll Read-Host herhalten, das Benutzereingaben von der Konsole liest. Ruf man Read-Host mit dem Parameter -Prompt auf, kann man den Benutzer zu einer Eingabe auffordern: 

$Password = Read-Host -Prompt "Bitte geben Sie ein Kennwort ein"

Das Kennwort wird als String in der Variablen $Password gespeichert. Leider wird das Kennwort aber bei der Eingabe im Klartext angezeigt. Das kann man über den Parameter -AsSecurestring verhindern. Dadurch wird die Eingabe in einen SecureString konvertiert und die Eingabe wird durch das * maskiert:

$Password = Read-Host -Prompt "Bitte geben Sie ein Kennwort ein" -AsSecureString
Bitte geben Sie ein Kennwort ein: ********

Markiert in:
Weiterlesen

Datums- und Zeitwerte Kulturunabhängig speichern

Wenn Sie Datums- und Zeitwerte speichern, gibt es ein ISO-Format, das Kulturunabhängig funktioniert. Es hat folgende Form:

yyyy-MM-dd HH:mm:ss (Jahr 4-stellig, Monat 2-stellig, Tag 2-stellig, Stunden im 24-Stunden Format, Minuten und Sekunden 2-stellig)

Sie können das Datumsformat mit Powershell im ISO-Format angeben, indem Sie den Format-Parameter verwenden: 

Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
2017-04-17 22:31:30

Speichern Sie das Datum in einer Variablen, erstellen Sie ein Datetime-Objekt. Der-Format-Befehl hat auf das Datetime-Objekt keine Auswirkungen, sondern bezieht sich nur auf die Ausgabe. Sie können das Datum also auch folgendermaßen Kulturunabhängig erzeugen:

Weiterlesen

Windows Server 2016 Startmenü findet keine Programm

Wie man viele Probleme mit dem Windows 10 Startmenü lösen kann, habe ich im Artikel "Suchen im Windows 10 Startmenü findet keine installierten Programme" bereits beschrieben. Leider tritt ein ähnliches Problem auch bei Windows Server 2016 auf, was das Startmenü ziemlich ad-absurdum führt. Mein erster Tipp hierzu: Verwenden Sie die Kachelanzeige, um häufig verwendete Programm einfach zu hinterlegen. 

Das eigentliche Problem der Suche im Startmenü unter Windows Server 2016 besteht darin, dass das Startmenü in Windows jetzt als Datenbank implementiert ist. Die Programme im Menü werden indexiert und in der Datenbank abgelegt. Der Zugriff findet dann über Cortana statt. Auf dem Windows Server 2016 hat Microsoft aber den Suchdienst deaktiviert, der die Suche durch die Datenbank erst ermöglicht. Nach langem Recherchieren habe ich einen Thread gefunden, der das Problem und die Lösung beschreibt. beschreibt. Ein Microsoft-Mitarbeiter hierzu:

The “Windows Search” service is set to ‘Disabled’ by default on Windows Server 2016. This is because indexing of the volumes can negatively impact / break server scenarios, such as Cluster Shared Volumes (CSV) and running Remote Desktop Session Host (RDSH) with multiple simultaneous sessions. The side effect of the Windows Search service being disabled is that using Cortana with Start Menu searches has a degraded experience.

Windows Server is optimized to ensure server scenarios are rock solid, which may include trade-off's over shell user experience. If you plan to use Windows Server 2016 as your client desktop machine, you could re-enable the Windows Search service.

Sie können das Problem mit dem Startmenü also einfach beheben, indem Sie die Dienstkonfiguration gehen und den Suchdienst starten oder einfach folgendes Powershell-Kommando verwenden:

Weiterlesen

VLAN-Tagging ab Windows Server 2012 einrichten (am Beispiel HP Proliant Microserver Gen8)

Was ist VLAN-Tagging überhaupt?

(Update: Eine sehr detailllierte Beschreibung zum Thema VLAN-Tagging habe ich bei Altaro gefunden: How to Set up VLANs in Hyper-V)

VLANs oder virtuelle LANs werden benutzt, um Switche zu segmentieren. Mit Hilfe eines VLANs kann man die Ports eines Switches, die normalerweise alle direkt miteinander kommunizieren, in getrennte Bereiche aufteilen. Man macht also aus einem Switch "mehrere" Switche. Das VLAN-Tagging innerhalb eines einzelnen physikalischen Switches passiert vollständig Switch-intern. Datenpakete, die den Switch verlassen, verhalten sich wie völlig normale Netzwerkpakete. Ein Switch kann bis zu 4096 VLANs verwalten. 

VLANs können auch über mehrer Switche hinweg konfiguriert werden. Das ist vor allem im Umfeld größerer Netze wichtig, wo z.B. Rechner unterschiedlicher Etagen sich im gleichen Netzwerk befinden sollen. Hierfür benötigt man VLAN-Tagging. Beim VLAN-Tagging wird auf einem Switch auf einem oder mehreren Ports VLAN-Trunking eingerichtet. Beim Trunking werden die ausgehenden Datenpakete mit einer VLAN-ID versehen, die ein Datenpaket einem bestimmten VLAN zuordnet. Ein Trunk-Port kann sich auch in mehr als einem VLAN befinden. Dadurch kann ein dedizierter Port zwischen zwei Switches bestimmt werden, über den die Switche die Datenpakete eines oder mehrer VLANs direkt austauschen können. Das entspricht einem Uplink zwischen zwei Switches, wobei jedes ausgehende Datenpaket genau einem VLAN zugeordnet ist. Da die aus einem Switch augehenden Datenpakete einen Marker für das jeweilige Zielnetzwerk enthalten, spricht man auch von einem getaggten VLAN. 

Solange man nur einen Switch mit VLANs segmentiert, hat man grundsätzlich Clientseitig keinerlei Probleme, da der Switch die Zuordnung der Datenpakete durchführt. Sobald man mit getaggten VLANs arbeitet, muß der Client wissen, für welches VLAN er Daten annehmen soll. Das kann man direkt in den Einstellungen der Netzwerkkarte vornehmen. Das entsprechende Feld heißt "VLAN ID". Außerdem muß die Unterstützung für VLANs aktiviert sein. Dieses Feld heißt z.B. "Priority & VLAN". 

Man kann eine Netzwerkkarte aber auch wie einen Trunk-Port einrichten, so dass sie die Daten von mehrern VLANs annimmt. Während das vor Windows Server 2012 über herstellerspezifische Tools wie die Broadcom Advanced Control Suite ( z.B. beim HP Proliant Microserver Gen8) ging, verwendet man dazu ab Server 2012 das NIC-Teaming. Tatsächlich hat die von HP zur Verfügung gestellte BACS das Teaming-Feature gar nicht mehr verfügbar, und wenn man die etwas aktuellere Version von Broadcom verwendet, schlägt das Einrichten der getaggten VLANs einfach fehl. 

Markiert in:
Weiterlesen

By accepting you will be accessing a service provided by a third-party external to https://netz-weise-it.training/

Nach oben