Quantcast
Channel: Neuste Artikel
Viewing all 119 articles
Browse latest View live

ODBC Datenquellen einrichten - 32 Bit, 64 Bit oder AD?

$
0
0

Viele Anwendungen benötigen zur Verbindung mit einem Datenbankserver eine ODBC-Datenquelle. Eine Datenquelle (oder auch DSN - Data Source Name) ist letztendlich nichts weiter als eine auf dem System hinterlegt Konfiguration, die der Anwendung sagt, wie Sie einen Datenbankserver über die ODBC-Schnittstelle (Open Database Connector) ansprechen kann. 

Wenn Sie auf Ihrem Rechner eine ODBC-Datenquelle konfigurieren wollen, können Sie hierfür einen Assitenten verwenden. Geben Sie dafür im Startmenü / Startbildschirm einfach ODBC ein. Windows sollte Ihnen dann zwei möglichen Konfigurationsprogramme anbieten: ODBC-Datenquellen (32-Bit) und ODBC-Datenquellen (64-Bit).

ODBC Datenquellen

Welche Datenquelle Sie benötigen, hängt dabei einzig von Ihrer Anwendung ab. Verwenden Sie eine 32-Bit Applikation (wie nach wie vor fast alle Office-Programme), benötigen Sie eine 32-Bit Datenquelle, für eine 64-Bit Applikation benötigen Sie eine 64-Bit Datenquelle. 

Die Unterschiede zwischen 32-und 64 Bit liegen im Detail. Zum einen werden unterschiedliche Treiber verwendet. Zum anderen werden, wenn Sie User- oder System-DSNs (Data Source Name) anlegen, 32-Bit-Schlüssel in der Registry nicht unter Software\ODBC angelegt, sondern unter Software\WOW6432Node\ODBC\. Daher ist wichtig, welchen Assistenten Sie zum Anlegen der Datenquelle verwenden. Beide heißen ODBCAD32.exe, liegen allerdings in unterschiedlichen Ordnern. Um beim Anlegen einer 32-Bit-Datenquelle sicher zu stellen, dass Sie wirklich den richtigen Assitenten verwenden, starten Sie den 32-Bit Assistenten am Besten direkt aus %windir%\SysWow64\odbcad32.exe. 

ODBC Datenquellen in Registry

Diese Registry-Werte können Sie über Gruppenrichtlinien (in den Gruppenrichtlinien-Einstellungen oder Prefrences) direkt wieder importieren und dann verteilen, ohne den Assistenten noch einmal bemühen zu müssen. Navigieren Sie dazu einfach in der Computer- oder Benutzerkonfiguration auf Preferences\Windows Settings\Registry und starten Sie über das Kontextmenü des Schlüssels unter dem Eintrag New den Registry-Wizard. Das setzt allerdings voraus, dass Sie die ODBC-Datenquelle auf dem Computer, auf dem Sie die Gruppenrichtlinie konfigurieren, vorher angelegt haben. 

Gruppenrichtlinie


Multifaktor-Authentifzierung (MFA) in Office 365 aktivieren und einsetzen

$
0
0

Mit Office 365 steht Ihnen seit einiger Zeit die Möglichkeit zur Verfügung, eine Multifaktor-Authentifzierung zu aktivieren, um die Sicherheit beim Login zu erhöhen. Was MFA ist, warum man es aktivieren sollte und wie das geht, zeigt Ihnen dieser Artikel.

Was ist MFA?

MFA steht für Multifaktor-Authentifizierung und bezeichnet ein Verfahren, bei dem ein Benutzer sich über mehrere Kritieren identifizieren muß. Klassischerweise identifiziert man sich über eine Kennwort, aber die reine Kenntwortauthentifizierung ist aus verschiedenen Gründen nicht wirklich sicher, denn so ein Kennwort kann z.B. abhanden kommen (jemand hat den Sticker unter der Tastatur gefunden) oder gehackt werden. Das ist vor allem schon deshalb sehr unangenehm, weil Kennwörter aufgrund der Komplexität oft schwer zu merken sind und von vielen Benutzern einfach nur mit einem Zähler versehen werden. Mit Wörterbuchattacken ist es außerdem oft sehr einfach, ein Kennwort innerhalb kurzer Zeit zu hacken. 

Die Idee hinter der Multifaktorauthentifizierung ist nicht neu. Schon Windows 2000 hat die Authentifizierung über Smartcards erlaubt. Mit MFA werden neben dem Geheimnis, das der Benutzer und der Anmeldeserver kennen (das Passwort), weitere Authentifzierungen gefordert. Bei der Smartcard ist das neben der PIN eben die Smartcard, die in den Leser geschoben werden muß. Bei RSA-Tokens ist das ein alle 30 Sekunden neu generierter Zahlencode. Der Vorteil liegt darin, dass die Kenntnis des Kennworts nicht ausreicht, um an die Benutzerdaten zu gelangen. Es wird mind. ein zweiter Faktor benötigt - in den meisten Fällen ein Stück "Hardware" - um die Authentifzierung abzuschließen. So ein Stück Hardware kann dabei prinzipiell alles sein, auch ein spezifisches Geräte. Das macht sich Microsoft z.B. mit Windows Passport zunutze, indem die Authentifizerung mit einer einfachen PIN durchgeführt wird, aber immer an ein spezifisches Geräte gebunden ist. 

Meistens ist so ein Stück Hardware aber teuer. Ein RSA-Token kostet pro Token viel Geld, für Smartcards benötigt man neben der Smartcard auch noch ein Lesegerät. Heutzutage trägt aber fast jeder ein Token freiwillig überall mit sich herum - das Smartphone. Daher ist MFA heutzutage recht erschwinglich geworden. Einmalcodes, wie Sie von RSA-Tokens generiert werden, können nämlich z.B. auch durch die Microsoft Authenticator App generiert werden, die auf allen mobilen Plattformen (Windows Phone, Android, IOS) zur Verfügung steht. Alternativ können Tokens auch per SMS oder Anruf übertragen werden. 

MFA in Office 365 aktivieren

Office 365 unterstützt über die Azure AD Integration seit einiger Zeit auch die MFA per Smartphone. Die Einrichtung hierfür ist recht simpel. Gehen Sie ins Office 365 Admin-Center, wählen Sie unter Users > Active Users einen Benutzer aus, und wählen Sie im Benutzermenü "Manage Multi-factor Authentication". 

1 MFA aktivieren

Anschliessend wählen Sie alle Benutzer aus, für die die MFA eingerichtet werden soll und wählen im rechten Menü "Quick Steps" den Eintrag "Enable".

2 enable MFA

Sie können erzwingen, dass mehrere Faktoren verwendet werden, indem Sie die Benutzer erneut auswählen und enforce aktivieren. 

3 enforce MFA

Das erzwingen führt dazu, dass alle Anwendungen bei der Anmeldung einen zweiten Faktor abfragen. Dummerweise unterstützen aber nur Web-Anwendungen die Authentifizierung per Smartphone. Daher benötigen Sie z.B. für Outlook oder Skype for Business noch ein App-Passwort. Das App-Passwort ist ein Kennwort, dass einmalig bei der nächsten Anmeldung in der Anwendung abgefragt wird. Der Benutzer benötigt es also nicht bei jedem Starten von Outlook, sondern nur beim ersten mal. Die Anwendung ist damit authentifziert. 

So sieht es der Benutzer

Der Benutzer muß, wenn die MFA erzwungen wird, bei der nächsten Anmeldung die MFA einrichten. Er wird beim Login über die Website direkt in das Einrichtungsmenü weitergeleitet.

 4 MFA einrichten

Hier kann er sich entscheiden, ob er die Authentifzierung per Anruf, per SMS oder per Authenticator-App ausführen möchte. Ich empfehle die Authenticator-App, die am einfachsen zu bedienen ist. Die App kann auch mehrere unabhängige Konten verwalten. Beim einrichten der App wird auf der Website einmal ein Barcode zum Einrichten der App angezeigt.

5_-_Prüfverfahren_wählen.png

Wählen Sie in der App dazu "Konto hinzufügen" aus und fotografieren Sie den Barcode ab. 

6 Prüfverfahren wählen

Nachdem "Die mobile App wurde für Benachrichtigungen und Prüfcodes konfiguriert" angezeigt wird, wählen Sie "Nehmen Sie Kontakt mit mir auf" aus. Das ist eine etwas seltsame Bezeichnung dafür, dass im nächsten Schritt der erste Prüfcode eingegeben werden muß... Der Prüfcode ist jeweils 30 Sekunden gültig und wird danach durch einen neuen ersetzt. Im letzten Schritt hinterlegen Sie eine Telefonnummer, um den Zugriff auf Ihr Konto wiederherzustellen, falls der Zugriff per App aus welchen Gründen auch immer nicht funktionieren sollte. 

7 Prüfverfahren wählen

Im folgenden Schritt wird ein App-Kennwort für den Benutzer generiert. Achtung, das App-Kennwort ist ebenfalls ein Einmal-Kennwort, es kann nach Schließen des Fensters nicht mehr angezeigt werden! Man kann App-Kennwörter als Benutzer aber selber generieren und verwalten. Das passiert in den Benutzereinstellungen. Öffnen Sie hierzu das Office 365-Portal unter https://portal.office365.com und greifen Sie oben rechts über Ihr Benutzericon auf "View Account" zu. 

8 Account verwalten

In den Account-Einstellungen wählen Sie "Security and Privacy" und hier im Untermenü "Additional Security verification" den Link "Update your phone numbers used for accounts security". 

9 Security and Privacy

Sie befinden Sich nun im Menü "Additional Security verification". Oben, leicht zu übersehen, gibt es aber noch eine zweite Registerkarte "App passwords". 

11 App Password

Hier können Sie neue Kennwörter anlegen. Wählen Sie dafür Create aus und geben Sie im folgenden Fenster einen Namen für das App-Kennwort ein. Sie können z.B. den Anwendungsnamen hinterlegen. 

12 Create app password

Im folgenden Fenster bekommen Sie das App-Kennwort angezeigt. Denken Sie daran, Sie kommen hinterher nicht mehr an das Kennwort heran. Im Zweifel müssen Sie ein neues generieren!

13 new password

Das App-Kennwort wird bei der nächsten Anmeldung von Outlook abgefragt. Sie bekommen zuerst eine erneute Abfrage des Kennworts, danach muß das App-Kennwort eingegeben werden. 

 

Links

Funktionsweise von Azure Multi-Factor Authentication - Feature-Vergleich kostenlos vs. Azure AD  Premium
Set Up mutli-factor authentication for Office 365 users
 
What are App Password in Azure MFA? 
Create an app password for Office 365 

 

 

Exchange-Commandlets in Powershell-Scripten nutzen

$
0
0

Wenn Sie Exchange 2013 oder 2016 per Powershell remote administrieren wollen, ohne sich auf den Exchange-Server per Powershell Remoting zu verbinden, oder wenn Sie Scripte von einer Management-Maschine aus starten wollen, brauchen Sie die Exchange-Snapins. Diese müssen Sie von den Exchange-Quellen nachinstallieren. Um die Installation starten zu können, müssen Sie allerdings eine Reihe von Software-Komponenten installiert haben. Am einfachsten geht dies über den Powershell-Befehl "Enable-WindowsoptionalFeature" auf dem Client bzw. Install-WindowsFeature auf dem Server:

Enable-WindowsOptionalFeature -Name IIS-WebServerRolead,IIS-WebServerManagementTools,IIS-IIS6ManagementCompatibility,IIS-Metabase,IIS-ManagementConsole,IIS-LegacySnapIn

Danach können Sie (für Exchange 2013) einfach über das Setup die automatisiert Installation der Exchange Management-Shell aufrufen:

Setup.exe /Role:ManagementTools /IAcceptExchangeServerLicenseTerms

Für die Installation können Sie einfach das aktuellste Exchange CU (Cumulative Update) nutzen, da das CU die komplette Exchange-Installation beinhaltet. 

Um die Exchange-Konsole zu starten, können nun die Exchange Management Shell starten. Die EMS startet automatisch die Powershell-Erweiterungen, die Exchange nach wie vor als Snap-Ins zur Verfügung stellt. Wenn Sie Exchange-Cmdlets aus einer bestehenden Powershell-Sitzung starten möchten, können Sie die Cmdlets einfach importieren, indem Sie das Script RemoteExchange.ps1 starten, dass sich im Exchange-Ordner befindet:

. 'C:\Program Files\Microsoft\Exchange Server\V15\bin\RemoteExchange.ps1'

Connect-ExchangeServer -auto -ClientApplication:ManagementShell 

Der Punkt vor dem Script-Pfad ist dabei relevant, denn er startet das Script dot-Sourced, was bedeutet, dass alle im Skript ausgeführten Befehle global gestartet werden. Wenn Sie den Punkt weglassen, sind alle Änderungen des Skripts nach Beendigung des Skripts wieder verschwunden. Connect-Exchangeserver verbindet dann Ihre Konsole mit Ihrem Exchange. 

Eine weitere Alternative ist es, die Snap-Ins manuell nachzuladen. 

$Snapins = "Microsoft.Exchange.Management.PowerShell.E2010","Microsoft.Exchange.Management.PowerShell.Setup","Microsoft.Exchange.Management.PowerShell.SnapIn","Microsoft.Exchange.Management.Powershell.Support"

Add-PSSnapin -Name $Snapins 

Diese Variante wird von Microsoft allerdings nicht supported. Sie führt u.a. dazu, dass Cmdlets wie Search-Mailbox direkt geladen werden, auch wenn der Benutzer kein Recht hat, die Mailboxen zu durchsuchen. 

Links

Connecting to Exchange 2010 with PowerShell

 

Emails in Exchange per Powershell suchen und löschen

$
0
0

Manchmal steht man vor der Aufgabe, das einzelne mails aus einem Benutzerpostfach gelöscht werden sollen, z.B. weil Sie Schadcode enthalten, oder auch, weil das Postfach geleert werden soll. Mit Hilfe der Exchange-eigenen Cmdlet Search-Mailbox geht das sehr einfach.

Starten Sie die Exchange Management-Shell. Eine Anleitung der Installation der Shell finden Sie im Artikel "Exchange Cmdlet in Powershell nutzen". Achten Sie darauf, dass Sie das Cmdlet "Search-Mailbox" nicht sehen, solange Sie nicht Mitglieder der Rolle "Mailbox Import Export" sind - das gilt sogar dann, wenn Sie als Organisationsadministrator angemeldet sind. Alternativ können Sie das Problem auch umgehen, indem Sie die Exchange-Snapins direkt importieren. 

Anschliessend rufen Sie das Cmdlet Search-Mailbox auf. Der Parameter Identity gibt dabei an, welche Mailbox(en) Sie suchen. Alternativ können Sie die Mailboxen auch per Pipeline an Search-Mailbox übergeben. Mit Hilfe des Parameters -Searchquery geben Sie an, welche Nachrichten gesucht werden. Das Cmdlet verwendet für die Definition der Suchabfragen die KQL (Keyword Query Language). Ein einfaches Beispiel für eine Suche nach dem Begriff "Verrat" in allen mails aller mailboxen sieht so aus: 

Get-Mailbox | Search-Mailbox -SearchQuery 'Verrat' -TargetMailbox 'Administrator' -TargetFolder 'NSA' 

 

Sie müssen für die Suche eine Zielmailbox und einen Zielordner in dieser Mailbox angeben, da das Cmdlet die mails natürlich nicht direkt anzeigen kann. 

Sie können auch mehrere Suchbegriffe miteinander verknüpfen. Dafür stellt Ihnen die KQL die drei Operatoren AND, OR und NOT zur Verfügung:

Get-Mailbox | Search-Mailbox -SearchQuery 'Verrat OR SPION OR BOMBE' -TargetMailbox 'Administrator' -TargetFolder 'NSA'

Sie können auch mehrer Bedingungen durch Klammern gruppieren:

Get-Mailbox | Search-Mailbox -SearchQuery 'Verrat AND (SPION OR BOMBE)' -TargetMailbox 'Administrator' -TargetFolder 'NSA' 

Die KQL unterstützt mit dem Stichwort NEAR(n) auch die Suche nach Wörtern, die nahe beieinander stehen, wobei (n) angibt, wie viele Wörter zwischen den beiden Suchwörtern stehen dürfen. Im folgenden Beispiel werden alle Kombinationen von Verrat mit Spion oder Bombe gesucht, die nicht mehr als 2 Zeichen voneinander entfernt stehen. 

Get-Mailbox | Search-Mailbox -SearchQuery 'Verrat NEAR(2) (SPION OR BOMBE)' -TargetMailbox 'Administrator' -TargetFolder 'NSA' 

Sie können auch Felder in der mail angeben, wie "Recipients:", "Subject:" oder "Body:".

Get-Mailbox | Search-Mailbox -SearchQuery 'Subject:Verrat' -TargetMailbox 'Administrator' -TargetFolder 'NSA'

Eine Suche nach allen Mails, die größer als 5 MB sind, verwendet das Feld "Size:"

Get-Mailbox | Search-Mailbox -SearchQuery 'Size:>10MB' -TargetMailbox 'Administrator' -TargetFolder 'NSA' 

Sie suchen gelöschte Mails? Auch kein Problem mit den Schlüsselwörtern -SearchDumpster und -SearchDumpsterOnly.

Get-Mailbox | Search-Mailbox -SearchQuery 'Subject:Verrat' -TargetMailbox 'Administrator' -TargetFolder 'NSA' -SearchDumpsterOnly 

Eine vollständige Auflistung der Schlüsselwörter, die in den Suchindex einfliessen, finden Sie unter "Message Properties indexed by Exchange Search". Eine Auflistung der Suchoperatoren finden Sie in der KQL-Referenz

Um die Daten nicht in eine andere Mailbox zu kopieren, sondern zu löschen, können Sie den Parameter -DeleteContent nutzen. Um Beispielsweise den Inhalt sämtlicher Mailboxen zu leeren (z.B. für Testumgebungen), können Sie folgendes Kommando nutzen:

Get-Mailbox -Identity Student* | Search-Mailbox -DeleteContent -Force

Get-Mailbox -Identity Student* sucht alle Postfächer, die mit Student beginnen,  und der Parameter -Force hinter -DeleteContent sorgt dafür, dass das Cmdlet nicht bei jeder Mailbox explizit fragt, ob die Daten wirklich gelöscht werden sollen. 

Eine Alternative zu Search-Mailbox stellt New-MailboxSearch dar. New-Mailboxsearch kann, im Gegensatz zu Search-Mailbox, auch Reports über Mailboxen erstellen. Mehr Informationen finden Sie im Blog "Just a UC Guy".

Links

KQL (Keyword Query Language)
Message Properties indexed by Exchange Search

Office 365 (nicht nur) auf einem RDP-Server installieren

$
0
0

Früher war es sehr einfach, Office auf einem Terminal Server zu installieren. Heutzutage ist die Installation auf einem RDP-Server komplizierter geworden. Nicht aufgrund der Installation, sondern aufgrund der Lizenzbedingungen. Denn ein Office 2016 kann nicht mehr einfach auf einem RDP-Server bereitgestellt werden - wenn es sich nicht um eine Volumenlizenz handelt, funktioniert die Installation zwar, aber danach startet das Office leider mit einer Fehlermeldung. 

Eine Alternative bietet sich an, wenn man Office 365 lizenziert hat. Die Installation ist allerdings wiederum nicht mit dem Aufrufen des Setups getan, da Office 365 eine alterantive Installationsmethode benötigt. Office 365 wird durch das Office Deployment Tool bereitgestellt, dass man bei Microsoft herunterladen kann. 

Die eigentlichen Installationschritte sind recht simpel. Office 365 wird in Form eine App-V Pakets installiert, dass von Microsoft bereitgestellt wird. Das Paket wird direkt bei Microsoft heruntergeladen, man benötigt also keine Installations-CD mehr. Das Herunterladen wird durch das Deployment Tool initialisiert. 

Damit nur die notwendigen Komponenten heruntergeladen werden, kann man dem Deployment-Tool über eine Konfigurations-Datei (Configuration.XML) sagen, welche Teile des Office-Paktes bereitgestellt werden sollen. Die Standarddatei sieht so aus:

<Configuration>
  <Add OfficeClientEdition="32" Channel="Current">
  <Product ID="O365ProPlusRetail">
     <Language ID="en-us" />
  </Product>
  <Product ID="VisioProRetail">
    <Language ID="en-us" />
  </Product>
</Add>
<!-- <Updates Enabled="TRUE" Channel="Current" /> -->
<!-- <Display Level="None" AcceptEULA="TRUE" /> -->
<!-- <Property Name="AUTOACTIVATE" Value="1" /> -->
</Configuration>

Die Datei gibt an, welche Produkte installiert werden, wie Updates bezogen werden (im übrigen bei Office 365 nicht mehr über Windows Update, sondern über ein administratives Share) usw. Die Datei ist nicht wahnsinnig komplex, aber trotzdem muß man die einzelnen zu setzenden Optionen kennen. Daher hat sich jemand hingesetzt und bei Github ein per Web verfügbares Tool entwickelt, um die Configuration.xml per GUI zu erstellen. Wichtig für die Lizenzierung auf dem RDP-Server ist, dass Sie die Option <Property Name="SharedComputerLicensing" Value="1"/> setzen. Hier ein Beispiel für eine Configuration.xml zur Installation auf einem RDP-Server, die nicht alle Programme installiert. 

<Configuration>
  <Add OfficeClientEdition="32">
     <Product ID="O365ProPlusRetail">
       <Language ID="en-us"/>
       <ExcludeApp ID="Groove"/>
       <ExcludeApp ID="Publisher"/>
     </Product>
  </Add>
  <Updates Enabled="FALSE"/>
  <Display Level="None" AcceptEULA="TRUE"/>
  <Logging Level="Standard" Path="%temp%"/>
  <Property Name="AUTOACTIVATE" Value="0"/>
  <Property Name="FORCEAPPSHUTDOWN" Value="FALSE"/>
  <Property Name="SharedComputerLicensing" Value="1"/>
  <Property Name="PinIconsToTaskbar" Value="TRUE"/>
</Configuration>

Nun müssen Sie nur noch die Setup.exe 2 mal aufrufen. Beim ersten Aufruf erstellen Sie das Installationspaket, beim zweiten Aufruf stellen Sie es bereit:

setup /download [Alternativer Pfad zur Konfigurationsdatei]
setup /configure [Alternativer Pfad zur Konfigurationsdatei]

Achten Sie darauf, dass der Benutzer beim Anmelden zuerst einmal eine Verknüpfung mit dem Office 365 Konto herstellen muß. Das kann nur dadurch verhindert werden, dass Sie auch ADFS (Active Directory Federation Services) in Ihrem AD implementieren. 

Links

Übersicht: Office Bereitstellungstools

Exchange-Cmdlets in Powershell-Scripten nutzen

$
0
0

Wenn Sie Exchange 2013 oder 2016 per Powershell remote administrieren wollen, ohne sich auf den Exchange-Server per Powershell Remoting zu verbinden, oder wenn Sie Scripte von einer Management-Maschine aus starten wollen, brauchen Sie die Exchange-Snapins. Diese müssen Sie von den Exchange-Quellen nachinstallieren. Um die Installation starten zu können, müssen Sie allerdings eine Reihe von Software-Komponenten installiert haben. Am einfachsten geht dies über den Powershell-Befehl "Enable-WindowsoptionalFeature" auf dem Client bzw. Install-WindowsFeature auf dem Server:

Enable-WindowsOptionalFeature -Name IIS-WebServerRolead,IIS-WebServerManagementTools,IIS-IIS6ManagementCompatibility,IIS-Metabase,IIS-ManagementConsole,IIS-LegacySnapIn

Danach können Sie (für Exchange 2013) einfach über das Setup die automatisiert Installation der Exchange Management-Shell aufrufen:

Setup.exe /Role:ManagementTools /IAcceptExchangeServerLicenseTerms

Für die Installation können Sie einfach das aktuellste Exchange CU (Cumulative Update) nutzen, da das CU die komplette Exchange-Installation beinhaltet. 

Um die Exchange-Konsole zu starten, können nun die Exchange Management Shell starten. Die EMS startet automatisch die Powershell-Erweiterungen, die Exchange nach wie vor als Snap-Ins zur Verfügung stellt. Wenn Sie Exchange-Cmdlets aus einer bestehenden Powershell-Sitzung starten möchten, können Sie die Cmdlets einfach importieren, indem Sie das Script RemoteExchange.ps1 starten, dass sich im Exchange-Ordner befindet:

. 'C:\Program Files\Microsoft\Exchange Server\V15\bin\RemoteExchange.ps1'

Connect-ExchangeServer -auto -ClientApplication:ManagementShell 

Der Punkt vor dem Script-Pfad ist dabei relevant, denn er startet das Script dot-Sourced, was bedeutet, dass alle im Skript ausgeführten Befehle global gestartet werden. Wenn Sie den Punkt weglassen, sind alle Änderungen des Skripts nach Beendigung des Skripts wieder verschwunden. Connect-Exchangeserver verbindet dann Ihre Konsole mit Ihrem Exchange. 

Eine weitere Alternative ist es, die Snap-Ins manuell nachzuladen. 

$Snapins = "Microsoft.Exchange.Management.PowerShell.E2010","Microsoft.Exchange.Management.PowerShell.Setup","Microsoft.Exchange.Management.PowerShell.SnapIn","Microsoft.Exchange.Management.Powershell.Support"

Add-PSSnapin -Name $Snapins 

Diese Variante wird von Microsoft allerdings nicht supported. Sie führt u.a. dazu, dass Cmdlets wie Search-Mailbox direkt geladen werden, auch wenn der Benutzer kein Recht hat, die Mailboxen zu durchsuchen. 

Links

Connecting to Exchange 2010 with PowerShell

 

Zertifikate mit Powershell Base64-kodiert aus dem Zertifikatsspeicher exportieren

$
0
0

Mit Powershell auf den Zertifikatsspeicher zurückzugreifen, ist sehr simpel, denn Powershell stellt für den Zugriff auf Zertifikate einen Powershell-Provider bereit. Durch den Provider ist es möglich, Zertifikate wie Dateien zu behandeln. Der Provider legt hierfür ein "Laufwerk" mit Namen Cert: an. Möchten Sie z.B. die Zertifikate des aktuellen Benutzers sehen, geben Sie ein:

PS C:\Users\Holger> Get-ChildItem -Path Cert:\CurrentUser\My\

PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                               Subject
----------                               -------
A83FA591D2D909D7465768ED4F7DE4019026F74D CN=Holger
7154EBF108BEB11587B1136B06EC5C24E3E6CAEA CN=NWCertRoot
6C0CEA5EC15CA5E6350CB9E7D02D90C9AA1DEBE3 CN=NwClientCert

Zurückgeliefert wird der eindeutige Thumbprint des Zertifikats, sowie dessen Name. Um ein Zertifikat ins Dateisystem zu exportieren, verwenden Sie das Cmdlet Export-Certificate:

Get-ChildItem -Path Cert:\CurrentUser\My\
  Where-Object { $_.subject -eq "cn=NWCertRoot" } |

  Export-Certificate -Type CERT -FilePath $home\NWCertRoot.cer 

Das klappt ganz wunderbar, allerdings unterstützt Export-Certificate nur den Export des Binärformats. Müssen Sie das Zertifikat Base64-Codiert ausgeben - also Text-kodiert - versagt Export-Certificate. Es ist allerdings einfach, das Zertifikat in seine Base64-kodierte Form zu bringen. Verwenden Sie hierfür die .Net-Klasse [Convert] und kodieren Sie die Eigenschaft .Raw des Zertifikatsobjekts:

$cert = Get-ChildItem -Path Cert:\CurrentUser\My\ | Where-Object { $_.subject -eq "cn=NWCertRoot" }

$Base64Cert = [convert]::tobase64string(($Cert).RawData,'InsertLineBreaks'

Nun können Sie die Base64-Form direkt aus den Speicher z.B. auf eine Website hochladen - z.B., wenn Sie in Azure ein Point-to-Site VPN erstellen wollen - oder Sie können das Zertifikat in einer Datei speichern. Für die Speicherung in eine Datei müssen allerdings noch die beiden Codes "-----BEGIN CERTIFICATE-----" vor und "-----END CERTIFICATE-----" nach dem Code eingefügt werden:

@"

-----BEGIN CERTIFICATE-----

$Base64Cert

-----END CERTIFICATE-----

"@ | out-file c:\temp\Base64Cert.Cer -Encoding ascii

 

Links:

https://social.technet.microsoft.com/Forums/en-US/37a213b9-f185-482e-b610-295f2056506e/export-certificate-using-base-64-cer-format-with-powershell-?forum=winserversecurity

Zertifikate mit Powershell inklusive des privaten Schlüssels als pfx-Datei exportieren

$
0
0

Im letzten Tipp habe ich gezeigt, wie man Zertifikate mit Powershell Base64-kodiert aus dem Zertifikatsspeicher exportieren kann. Wenn man versucht, mit dem Cmdlet Export-Certificate eine pfx-Datei zu erstellen, - die pfx-Datei ist ein Container, der neben dem Zertifikat auch den privaten Schlüssel enthält und tatsächlich eigentlich das PKCS #12-Formate enthält - stellt man allerdings fest, dass das Cmdlet dazu nicht in der Lage ist. Tatsächlich ist es aber kein Problem - man muß nur das richtige Cmdlet verwenden. Denn zum Export als .pfx-Datei verwendet man Export-PFXCertificate. Die Datei muß allerdings mit einem Kennwort gesichert werden, um den privaten Schlüssel zu  sichern:

$pwd = ConvertTo-SecureString -String "geheim" -AsPlainText -Force

Get-ChildItem -Path Cert:\CurrentUser\My\ | Where-Object { $_.subject -eq "cn=NWCertRoot" } |

    Export-PfxCertificate -FilePath $home\NwcertRoot.pfx -Password $pwd 

 

Links:

https://en.wikipedia.org/wiki/PKCS_12


Azure Standard VHD Storage verwalten - aktivieren Sie Trim und sparen Sie Geld

$
0
0

Virtuelle Maschinen in Windows Azure speichern Ihre Daten genau wie in Hyper-V in VHD-Dateien. Azure unterstützt dabei allerdings nur das Fixed Size VHD-Format, also weder VHDX noch dynamische Vergrößerung.

Fixed Size VHDs werden bereits bei der Erstellung der VHD mit der Gesamtgröße der Datei angelegt. Erstellen Sie also eine Datei mit 100 GB Größe, nimmt diese auch 100 GB Speicherplatz auf dem Datenträger ein. Damit die Daten auf dem Storage in Azure aber nicht durch Leerdaten zugemüllt werden (und Sie leere Festplatten auch nicht bezahlen müssen, denn die VHDs werden u.a. über den verwendeten Speicherplatz bezahlt), verwaltet der Azure-Storage die VHD-Dateien als Sparse-Daten, was nichts anderes heißt als dass nur die wirklich verwendeten Bereiche der VHD-Datei gespeichert werden. Damit das effizient passieren kann, muss die VM in regelmässigen Abständen der Festplatte (also der VHD) mitteilen, welche Daten wirklich gelöscht wurden - normalerweise entfernen Löschvorgänge nur die Einträge in der Verwaltungsdatei des Dateisystems, bei NTFS die MFT oder Master File Table. Der Datenträger bekommt also gar nicht mit, welche Daten nicht mehr verwendet werden. Spätestens seit SSDs wissen wir, dass es eine gute Idee ist, dem Datenträger ebenfalls mitzuteilen, welche Speicherbereiche gelöscht wurden. Das passiert über den Trim-Befehl, der das Dateisystem mit dem Datenträger abgleicht.

Für in Standard-Storage (nicht auf SSD) abgelegte, manuell verwaltete ("Ungemanagte") Datenträger sollten Sie prüfen, ob Trim aktiviert ist - bei allen andern Varianten wird das automatisch verwaltet. Öffnen Sie hierfür in der Azure-VM eine Kommandozeile und verwenden Sie das File-System-Utility (fsutil.exe) zum prüfen:

fsutil behavior query DisableDeleteNotify

Wenn fsutil 1 zurück gibt, ist Trim deaktiviert. Zum aktivieren verwenden Sie folgenden Befehl:

fsutil behavior set DisableDeleteNotify 0

 

Links

https://docs.microsoft.com/en-us/azure/storage/storage-about-disks-and-vhds-windows

Suchen im Windows 10 Startmenü findet keine installierten Programme

$
0
0

Wenn Sie Windows 10 installiert haben und sich regelmässig darüber ärgern, dass die Suche installierte Desktop-Programme nicht findet, hier 2 Tipps, die helfen. Achten Sie darauf, dass Sie für beide Aktionen Administrator-Rechte benötigen. 

Tipp 1 - Installieren Sie die Cortana-App neu

Anscheinend hat die Cortana App ein Problem, das sich mit einer Neuinstallation beheben lässt. Öffnen Sie hierfür zuerst ein administratives Powershell-Fenster (rechtklick auf das Powershell-Icon und "Als Administrator ausführen" wählen. 

Als nächstes beenden Sie den Windows Explorer. Der von Microsoft vorgesehene Weg führt dazu über einen Rechtsklick bei gedrückt gehaltener Strg+Shift-Taste auf die Taskleiste. Im Kontextmenü erscheint als unterster Punkt "Explorer beenden". 

explorer beenden

Nun registrieren Sie die Cortana-App in Powershell neu:

Get-AppXPackage -Name Microsoft.Windows.Cortana | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"

Tipp 2 - Starten Sie die Indexierung neu

Falls das nicht helfen sollte, hilft es unter Umständen, den Suchindes neu zu erstellen. Diese Prozedur kann allerdings einige Stunden dauern, bevor sie abgeschlossen ist. Öffnen Sie dafür die klassische Systemsteuerung (Windows +X drücken und dann "Systemsteuerung" auswählen) und schalten Sie die Anzeige auf "große Symbole" um. Öffnen Sie die Konfiguration für "Indizierungsoptionen", wählen Sie "Erweitert" und starten Sie die Reindizierung über "Problembehandlung > Neu erstellen". 

Links:

https://answers.microsoft.com/en-us/windows/forum/windows_10-win_cortana/cortana-not-finding-desktop-apps-when-searching/f612e995-6664-4b91-b6ae-96790e763858

Mit [ValidateScript()] Powershell-Parameter prüfen und eine benutzerdefinierte Fehlermeldung ausgeben

$
0
0

Powershell stellt mit den Validate-Schlüsselwörtern eine großartige Möglichkeit zur Verfügung, Benutzereingaben in Skripten zu prüfen, und den Code dabei übersichtlich zu halten. Hierfür stehen diverse [Validate]-Attribute zur Verfügung. Folgendes Beispiel prüft z.B. ob ein Parameter sich innerhalb eines bestimmten Wertebereichs befindet:

param(
   [ValidateRange(1,6)]
   [int]$Wuerfelergebnis
)

Rufen Sie den Parameter jetzt z.B. mit 7 auf, erhalten Sie folgende Meldung und das Skript bricht ab:

test : Das Argument für den Parameter "Wuerfelergebnis" kann nicht überprüft werden. Das 7-Argument ist größer als der maximal zulässige Bereich von 6. Geben Sie ein Argument an, das kleiner oder gleich 6
ist, und führen Sie dann den Befehl erneut aus.

Es gibt eine ganze Reihe von Validierungs-Attributen. Eine vollständige Auflistung finden Sie, wenn Sie in der Powershell 

get-help about_Functions_Advanced_Param -ShowWindow

eingeben. Falls Sie kein passendes Validierungsattribut finden, ist aber noch nicht alles verloren, denn dann können Sie immer noch [ValidateScript()] verwenden. ValidateScript führt ein Skript zur Überprüfung aus, dass True zurück geben muß, damit der Parameter als gültig angesehen wird. Um Beispielsweise die Existenz eines übergebenen Ordner zu prüfen, verwenden Sie folgenden Code:

[ValidateScript({ Test-Path -Path $_ -PathType Container } )
[string]$path

Test-Path liefert True zurück, wenn der übergebene Pfad ein gültiger Ordner ist, und False, wenn der Ordner nicht existiert. Der Parameter selbst wird über die anonyme Variable $_ angegeben, da er erst nach er Prüfung erstellt wird. Leider ist die Fehlermeldung von [ValidateSkript()] für den Endbenutzer sehr nichtssagend: 

test : Das Argument für den Parameter "Path" kann nicht überprüft werden. Das Validierungsskript "Test-Path -Path $_ -PathType Container" für das Argument mit dem Wert "c:\murks" hat nicht "True" zurückgegeben. Ermitteln Sie, weshalb beim Validierungsskript ein Fehler aufgetreten ist, und führen Sie den Befehl erneut aus.

Allerdings gibt es einen Trick, um doch noch zu einer Benutzerdefinierten Fehlermeldung zu kommen. Wenn Sie die Ausgabe von Test-Path in einer IF-Abfrage abfangen, können Sie die Fehlerfall selbst behandeln. Leider bringt es nichts, einfach eine Fehlermeldung auszugeben, da diese vom IF als True ausgewertet wird anstatt zu False:

[ValidateScript({ If ( Test-Path -Path $_ -PathType Leaf )
                      { $true }
                  Else { "Es ist ein Fehler aufgetreten" }
})]

Die Fehlermeldung bleibt die gleich wie oben. Sie können allerdings das Skript vorher selber mit einem terminierenden Fehler abbrechen lassen, so dass die von Powershell generierte Fehlermeldung gar nicht mehr aufgerufen wird. Einen Benutzerdefinierten Fehler können Sie mit dem Befehl THROW generieren. Das fertige Prüfskript sieht dann so aus:

[ValidateScript({ If ( Test-Path -Path $_ -PathType Container )
                              { $true }
                           Else { Throw "$_ is not a valid Directory" }
})]

Ab Powershell 3.0 können Sie die Validierungsattribute sogar an Variablen im Code durchführen, während das vorher nur im param-Block möglich war.

Zufällige (Komplexe) Kennwörter erzeugen mit Powershell

$
0
0

Kennwörter braucht man in Skripten an allen Ecken und Enden, speziell dann, wenn man Benutzer erstellen möchten. Bei einer größeren Anzahl von Konten kann da ein Skript ganz hilfreich sein, dass zufällige Kennwörter generiert. Das ist mit Powershell relativ einfach gemacht. Alles, was man benötigt, ist eine Funktionalität zum Erstellen von Zufallswerten und die Möglichkeit, Zahlen in Buchstaben umzuwandeln. Das Cmdlet Get-Random liefert Zufallszahlen zurück:

Get-Random -Min 10 -Max 100

Die vollständige Auflistung der Funktionen Get-Random können Sie in der Powershell-Hilfe nachlesen. Für uns interessant ist der Parameter -Inputobject, über den man Get-Random ein Array mit Werten übergeben kann, aus denen der Zielwert gewählt wird. 

$ZufallsListe = 65..90
$Zufallszahl = Get-Random -InputObject $Zufallsliste

Die Zahlen 65-90 entsprechen den Ascii-Codes der Großbuchstaben von A-Z. Wir können die Zahlen in einen ASCII-Code umwandeln, indem wir Sie in ein CHAR[]-Array konvertieren. 

[CHAR[]]$Zufallszahl

Wenn man den Code in einer Schleife ausführt, bekommt man ein zufällig generiertes Kennwort:

$Length = 12
$Zufallsliste = 65..90
For ( $i = 0; $i -lt 12; $i++)
{
    $password += Get-Random -InputObject $Zufallsliste
}

Jetzt kann man noch weitere die Zahlenrepräsentationen für Kleinbuchstaben, Zahlen und Sonderzeichen hinzufügen und alles in eine Funktion packen, und man hat "New-Password":

function New-Password {
<#

[cmdletBinding()]
param
(
   # The Length of the Password
   [String]
   [ValidateRange(3,256)]
   [Parameter()]
   $Length = 12,

   # The Criteria the Password must fullfill. Only Complex enforces the combination of
   # different Criteria.
   [ValidateSet('Complex','Numbers','Specials','LowerCaseLetters','UpperCaseLetters')]
   [String[]]
   $type = 'Complex'
)

# ASCII-Codes for different Types of Characters as Arrays
$Specials = ( 33..45 ) + ( 58..64 ) + ( 91..95 )
$Numbers = ( 48..57 )
$UpperCaseLetters = 65..90
$LowerCaseLetters = 97.. 122

# Generate the Array $Charset which contains the Characters from all chosen Criteria
Switch ( $Type )
{
   'Complex'          { $Charset = $UpperCaseLetters + $LowerCaseLetters + $Numbers + $Specials; break }
   'UpperCaseLetters' { $Charset += $UpperCaseLetters }
   'LowerCaseLetters' { $Charset += $LowerCaseLetters }
   'Numbers'          { $Charset += $Numbers }
   'Specials'         { $Charset += $Specials }
}
Write-Verbose "$Charset"

# Generate the password. The While-Loop ensures that Complex Passwords fullfill at least 3 Criteria.
While ((( $UpperInserted + $LowerInserted + $SpecialsInserted + $NumbersInserted -lt 3 ) -and ( $type -eq 'Complex' )) `
           -or (( $type -ne 'Complex' ) -and ( $UpperInserted + $LowerInserted + $SpecialsInserted + $NumbersInserted -lt 1 )))

{
   # Count-Variables are for reporting purposes
   # Inserted-Variables ensure that complex Passwords fullfill always at least 3 Criteria.
   # They are checked in the While-Condition.
   $UpperCount = 0
   $LowerCount = 0
   $SpecialsCount = 0
   $numbersCount = 0
   $UpperInserted = 0
   $LowerInserted = 0
   $SpecialsInserted = 0
   $NumbersInserted = 0
   [string]$Password = ''

   # Generating the Password
   For ( $i=1; $i -le $Length; $i++ )
   {
      $RandomChar = (Get-Random -InputObject $CharSet)
      Switch ( $RandomChar )
      {
         { $RandomChar -in $UpperCaseLetters } { $UpperCount++; $UpperInserted = 1 }
         { $RandomChar -in $LowerCaseLetters } { $LowerCount++; $LowerInserted = 1 }
         { $RandomChar -in $Specials } { $SpecialsCount++; $SpecialsInserted = 1 }
         { $RandomChar -in $Numbers } { $NumbersCount++; $NumbersInserted = 1 }
      }
      [string]$Password += [char[]]$RandomChar
   }
}

$Password
Write-Verbose "UpperCaseCount: $UpperCount"
Write-Verbose "LowerCaseCount: $LowerCount"
Write-Verbose "Specials: $SpecialsCount"
Write-Verbose "Numbers: $numbersCount"
}

Links

New-Password.txt

DHCP-Server migrieren mit Powershell

$
0
0

Ich stand am Wochenende vor der Aufgabe, unseren Fileserver zu migrieren, der auch als DHCP-Server fungiert. Anstatt alle Scopes neu anzulegen, habe ich mit Powershell eine sehr einfache Möglichkeit gefunden, alle DHCP-Scopes, Leases und Einstellungen auf einen Rutsch zu migrieren. Alles, was dafür getan werden muß, ist die DHCP-Einstellungen per 

Export-DHCPServer -File <Export.xml>

zu exportieren. Die Konfiguration wird in eine XML-Datei exportiert und kann auf dem Zielserver einfach über 

Import-DHCPServer -File <Export.xml> 

wieder importiert werden. 

Die Cmdlets stehen ab Windows Server 2012 zur Verfügung. Mit Hilfe des Parameters -Computername kann aber auch ein Remote-DHCP-Server angegeben werden, der noch unter einer älteren Windows-Version läuft:

Export-DHCPServer -File <Export.xml> -Computername DHCP2008

Mit den Parameter -ScopeID, -Prefix und -Leases kann man außerdem einschränken, welche Daten migriert werden sollen. 

Links

Technet: Export-DHCPServer

 

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

$
0
0

Was ist VLAN-Tagging überhaupt?

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. 

Vielleicht fragen Sie sich jetzt, warum man das überhaupt machen möchte. Das ist dann sinnvoll, wenn Sie einen Server haben, der in mehreren getrennten Netzwerken eine Verbindung haben soll (Multihomed), wie z.B. ein DHCP-Server oder ein Router, sie aber nicht für jedes Netzwerk eine eigene physikalische Netzwerkkarte verfügbar haben.

Einrichten von getaggten VLANs ab Windows Server 2012

Starten Sie zuerst den Netzwerkkarten-Teaming-Manager aus dem Windows Server Manager (Lokaler Server->NIC Teamvorgang) oder über lbfoadmin.exe. Im Teaming-Manager legen Sie dann zuerst über Teams->Aufgaben ein neues Team an. 

1 Neues TEam erstellen

Wählen Sie die Netzwerkkarte aus, für die mehrere VLANs konfiguriert werden sollen. Das ist in unserem Beispiel nur eine Netzwerkkarte, daher besteht auch das Team nur aus einer Karte. Die weiteren Einstellungen sind daher auch irrelevant, da Sie erst einen Einfluß haben, wenn Sie ein Team aus mehr als einer Netzwerkkarte anlegen. 

 

2 Team konfigurieren

Anschließend wird ein weiteres Interface (eine zusätzliche "Netzwerkkarte") hinzugefügt. Hierfür wechseln Sie unter "Adapter und Schnittstellen" auf die Registerkarte "Teamschnittstellen" und wählen unter Aufgaben "Schnittstelle hinzufügen". 

 

3 Schnittstellte hinzufügen

Vergeben Sie der Schnittstelle einen sprechenden Namen, da ansonsten das auseinanderhalten der neuen Schnittstellen schwierig wird, und tragen Sie die VLAN-ID unter "spezifisches VLAN" ein. 

 

4 VLAN ID

Wiederholen Sie diesen Schritt für jedes VLAN, für den die Schnittstelle Datenpakete empfangen soll. Für jedes Interface, dass Sie anlegen, wird eine neue Netzwerkkarte in der Netzwerkkartenkonfiguration hinzugefügt. Anschließend vergessen Sie nicht, auch dem ersten erstellen Interface eine VLAN-ID zu vergeben, wenn diese nicht auf dem Standard verbleiben soll. Wählen Sie hierzu das Interface aus und rufen aus dem Kontextmenü die Eigenschaften auf. 

5 Interface bearbeiten

Anschließend finden Sie in der Netzwerkverwaltung für jedes angelegte Interface eine Netzwerkkarte vor. Achten Sie darauf, dass Sie das eigentliche physikalische Interface nicht mehr verwenden können. Es ist jetzt an das "Microsoft-Muliplexorprotokoll für Netzwerkkarten" gebunden. 

6 die neuen Netzwerkkarten

 

Links

HP Proliant Microserver Gen8 Treiber
Wikipedia: Virtual Local Area Network

Windows Server 2016 Startmenü findet keine Programm

$
0
0

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:

Set-Service -Name WSearch -StartupType Automatic -Status Running

Wie Microsoft aber so schön schreibt: Auf eigene Gefahr. Man darf sich nur wundern, wie Microsoft es schafft, ein Startmenü zu implementieren, dessen Suchfunktion man speziell auf einem RDP-Server, der Desktopersatz sein soll, nicht mehr einschalten soll...

Links

Windows Server 2016 Start Menu Not Showing All Items and Version Strings Inconsistent


Datums- und Zeitwerte Kulturunabhängig speichern

$
0
0

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:

Get-Date -Year 2017 -Month 4 -Day 17
Montag, 17. April 2017 22:36:10

Links

Serializing Date and Time in a Culture-Invariant Way

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

$
0
0

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: ********

Wenn man mit dem Kennwort z.B. ein PSCredentialObjekt erzeugen möchte, ist alles Super, denn dann braucht man das Kennwort nicht einmal mehr in einen SecureString umzuwandeln. Wenn man aber das Kennwort im Klartext benötigt, hat man ein Problem. Der SecureString stellt nämlich keine Möglichkeit zur Verfügung, das Kennwort wieder in Klartext umzuwandeln. Glücklicherweise bietet das PSCredential-Objekt aber so eine Möglichkeit, nämlich die Methode GetNetworkCredential(). Um das Kennwort wieder im Klartext zu sehen, hier das komplette Skript: 

$Password = Read-Host -Prompt "Bitte geben Sie ein Kennwort ein" -AsSecureString
$Credential = New-Object -TypeName PSCredential("Holger",$Password)
$credential.GetNetworkCredential().Password

Links

Create Scheduled Tasks with Secure Passwords

Windows Data Protection API

 

Inaktive Benutzer oder Computer mit Powershell finden und deaktivieren

$
0
0

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

Um das ganze praktisch problemlos einsetzen zu können, habe ich eine kleine Funktion gebastelt, die alle inaktiven Konten deaktiviert, in eine eigene OU verschiebt, und das Beschreibungsfeld des Kontos verwendet, um den Ursprungsort und das Datum des Verschiebens zu dokumentieren. So können Sie alte Konten sicher deaktivieren und archivieren, ohne den Kollegen mitsamt seinem PC aus Ihrem AD zu entfernen, der sich gerade im Sabbatjahr oder in Elternzeit befindet. Die verschobenen Konten werden in einer csv-Datei protokolliert. 

Function Move-InactiveAccounts
{
  <#
      .SYNOPSIS
      Finds inactive Accounts, comments and disables them and moves them into an OU for disabled Accounts
      .DESCRIPTION
      This Function uses Search-ADAccount to find inactive Accounts. It moves inactive Accounts to a special
      OU, disables them and comments the day and the original OU in the comment-Field of the Account.
      All moved accounts are documented in a csv-File for reference. The system-Accounts guest,krbtgt and Default Account
      are not touched.
      .PARAMETER TargetOU
      The OU where disabled accounts are moved to
      .PARAMETER logFilePath
      The CSV-File which is created to document which accounts where touched.
      .PARAMETER AccountsToIgnore
      Add Additional Accounts which shall be ignored beside the system-accounts
      .PARAMETER AccountType
      User,Computer or all defines which accounts shall be examined.
      .EXAMPLE
      Move-InactiveAccounts -TargetOU "OU=Inactive,DC=netz-weise,dc=de" -logFilePath c:\log\disabledUsers.csv -AccountsToIgnore 'admin' -AccountType User
      Describe what this call does
      .NOTES
      Author: Holger Voge
      Website: www.Netz-Weise-it.Training
      Date: 23.04.2017
      Version: 1.0
  #>

  param
  (
    [String]
    [Parameter(Mandatory)]
    [string]
    $TargetOU = 'DisabledAccounts',
    [string]
    [Parameter()]
    [string]$logFilePath = "$env:temp\DisabledUsers.csv",
    [string[]]$AccountsToIgnore,
    [ValidateSet("User","Computer","All")]
    [string]$AccountType = "user",
   
    [int]$InactivityDays = 90
  )
  $domainDN = (Get-ADDomain).DistinguishedName
  $TargetOUDN = "OU=$TargetOU,$domainDN"
  $ExcludeAccounts = 'Krbtgt','guest','DefaultAccount','administrator',$AccountsToIgnore
  Try {
    $Null = Get-ADOrganizationalUnit -Identity $TargetOUDN
  }
  Catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException] {
    Return "Die übergebene OU existiert nicht"
  }
  [array]$InactiveAccountList = Search-ADAccount -AccountInactive |
    Where-Object { ( $_.Name -notin $ExcludeAccounts ) -and ( $_.DistinguishedName -notlike "*$TargetOUDN" ) }
  foreach ( $InactiveAccount in $InactiveAccountList )
  {
    $description = ( Get-ADObject -Identity $InactiveAccount.DistinguishedName -Properties Description ).description
    $description = "{0}`nOrigin: {1}`nMoveDate: {2}" -f $description,$InactiveAccount.DistinguishedName,(get-date -Format yyyy-MM-dd)
    Set-ADObject -Identity $InactiveAccount.DistinguishedName -Description $description
    Disable-ADAccount -Identity $InactiveAccount -PassThru | Move-ADObject -TargetPath $TargetOUDN
    $InactiveAccount | Select-Object name,distinguishedName,LastLogonDate,Description,@{ name="Movedate";expression={get-date -Format "yyyy-MM-dd hh-mm-ss"}} |
      export-CSV -Path $logFilePath -UseCulture -Encoding UTF8 -NoTypeInformation -Append
  }
  "Die Protokolldatei wurde unter $logFilePath gespeichert"
}

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

$
0
0

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ß. 

In eine Funktion gegossen sieht das dann so aus: 

function New-Password {
   param
   (
      # The Length of the Password
      [ValidateRange(3,128)]
      [String]$Length = 12,

      # Number of non-Alpanumeric Characters
      [String]$Specials = '3'
)

   Add-Type -AssemblyName System.web
   [System.Web.Security.Membership]::GeneratePassword($Length,$Specials)
}

Links:

Membership.GeneratePassword Method

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

$
0
0

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
Viewing all 119 articles
Browse latest View live