Archive for the ‘Powershell V4’ Category

Vorhandene Windowsversionen aus Windows-Installations-ISO-Datei ausgeben

30 Dezember 2014

Wenn man eine Windows-Installations-ISO-Datei hat und schnell wissen möchte, welche Versionen darin enthalten sind, gibt es verschiedene Möglichkeiten dies herauszufinden.

Wenn man Windows 8 oder neuer hat, dann kann man dies mittels Powershell über diesen Einzeiler:

$m=Mount-DiskImage -ImagePath "C:\Temp\MS-ISOs\de_windows_8.1_with_update_x64_dvd_6051485.iso" -PassThru ; Get-WindowsImage -ImagePath "$(($m| Get-Volume).DriveLetter):\sources\install.wim";
$m|Dismount-DiskImage

Führt zum Ergebnis:

Index       : 1
Name        : Windows 8.1 Pro
Description : Windows 8.1 Pro
Size        : 13.324.853.116 bytes

Index       : 2
Name        : Windows 8.1
Description : Windows 8.1
Size        : 13.260.872.008 bytes

Der Reihe nach:

$m=Mount-DiskImage -ImagePath "C:\Temp\MS-ISOs\de_windows_8.1_with_update_x64_dvd_6051485.iso" -PassThru ;

Öffnet eine ISO-Datei und reicht das Objekt an $m weiter.

Get-WindowsImage -ImagePath "$(($m| Get-Volume).DriveLetter):\sources\install.wim";

Ermittelt den bei Mount-DiskImage vergebenen Laufwerksbuchstaben und schaut unter diesem im Verzeichnis nach der X:\Sources\Install.WIM-Datei. Dort werden mittels Get-WindowsImage die verfügbaren Versionen ermittelt und ausgegeben.

$m|Dismount-DiskImage

Entfernt das eingehängte ISO-Image wieder. Das wars.

Werbeanzeigen

Für Powershell .Net Framework Tracing aktivieren

13 Dezember 2014

Manchmal ist nicht klar warum etwas nicht funktioniert. Da Powershell stark auf das .Net Framework angewiesen ist, kann man auch dessen Trace-Möglichkeiten nutzen, um eine tiefergehende Fehleranalyse zu ermöglichen. Hilfreich ist das Tracing z. B. in Verbindung mit der Netzwerkkommunikation.

Unter .Net kann man das Netzwerktracing wie in diesem Artikel beschrieben aktivieren: http://msdn.microsoft.com/en-us/library/ty48b824(v=vs.110).aspx. Damit der Trace-Mitschnitt in Powershell aktiviert werden kann, muss die in der betreffenden Powershellversion die Datei Powershell.exe.config angelegt, bzw. bearbeitet werden. Dabei ist von Bedeutung, ob man mit Powershell 32-Bit oder 64-Bit arbeitet. Zum Thema Powershell 32-/64-Bit siehe hier: https://newyear2006.wordpress.com/2012/06/20/prfen-ob-eine-powershell-sitzung-in-einer-32bit-oder-64bit-prozess-umgebung-luft/.

Kurz: Unter einem 64-Bit System findet man die 64-Bit Powershell-Version unter C:\WINDOWS\SYSTEM32\WINDOWSPOWERSHELL\V1.0 und die 32-Bit Powershell-Version unter C:\WINDOWS\SYSWOW64\WINDOWSPOWERSHELL\V1.0. Auf einem reinen 32-Bit-System ist der Pfad wieder wie bei der 64-Bit Fassung.

Wenn man nun also seine Powershell.exe.config, die so aussieht

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

   <system.diagnostics>

        <sources>

            <source name="System.Net">

                <listeners>

                    <add name="System.Net"/>

                </listeners>

            </source>

            <source name="System.Net.Sockets">

                <listeners>

                    <add name="System.Net"/>

                </listeners>

            </source>

        </sources>

        <switches>

            <add name="System.Net" value="Verbose" />

            <add name="System.Net.Sockets" value="Verbose" />

        </switches>

        <sharedListeners>

            <add name="System.Net"

                type="System.Diagnostics.TextWriterTraceListener"

                initializeData="System.Net.log"

                />

        </sharedListeners>

        <trace autoflush="true" />

    </system.diagnostics>

</configuration>

im Verzeichnis C:\Windows\System32\WindowsPowershell\V1.0\ angelegt hat, kann man anschließend Powershell starten. Wichtig, die Einstellungen wirken sich erst aus, wenn eine neue Powershell.exe gestartet wird.

Man bekommt nun in der Datei System.Net.Log die Trace-Daten gespeichert. Die System.Net.Log wird in dem Verzeichnis der Powershell.exe gespeichert.

Möchte man die Trace-Möglichkeit in Powershell-ISE nutzen, muss man natürlich die Datei Powershell_ise.exe.config bearbeiten.

Das Format der Trace-Daten ist kurz hier angerissen: http://msdn.microsoft.com/en-us/library/46fcs6sz(v=vs.110).aspx.

Fehlende Cmdlets in Powershell durch Polyfills nachbilden

17 November 2014

In der HTML5-Welt sind Polyfills ein fester Begriff. Es geht um das Nachrüsten von Funktionen, die in bestimmten Browsern nicht vorhanden sind. Die Definition stammt von Remy Sharp einer der Größen in der HTML5/Javascript-Welt https://remysharp.com/2010/10/08/what-is-a-polyfill.

Was hat das mit Powershell zu tun? Auch in Powershell haben wir das Problem, dass Microsoft es wegen Menpowerproblemen oder strategischen Gründen nicht geschafft hat, Cmdlets aus Windows 8 zurückzuportieren für Windows 7. Ein Beispiel ist Rename-Printer. http://technet.microsoft.com/en-us/library/hh918360.aspx. Oder ein neues kommendes Cmdlet ist Expand-Archive aus Windows 10, welches sicher auch auf alten Windows Versionen benötigt wird.

Polyfills, sogenannte Drop-in Polyfills, wie im Buch “Building Polyfills” von Brandon Satrom definiert, prüfen, ob eine bestimmte Funktion vorhanden ist, wenn diese fehlt, wird diese nachimplementiert. Ist die Funktion bereits vorhanden, so wird die bestehende native Funktion verwendet. In Powershell kann man genau dieses verhalten nachbilden.

Zunächst muss man herausfinden, ob ein bestimmtes Cmdlet verfügbar ist. Zunächst sollte dazu das zugehörige Modul geladen werden. Als zweites sollte dann mittels Get-Command abgefragt werden, ob das betreffende Cmdlet vorhanden ist.

Die Prüfung, ob Rename-Printer vorhanden ist, sieht z. B. so aus:

if (-not (Get-Command Rename-Printer -ErrorAction SilentlyContinue))
{
       # Rename-Printer ist nicht vorhanden
}

Wichtig dabei ist der Parameter –ErrorAction SilentlyContinue, der dafür sorgt, dass wenn das Cmdlet nicht vorhanden ist, keine Fehlermeldung erscheint.

Wie könnte nun ein konkreter Nachbau von Rename-Printer aussehen? Früher hatte man so etwas über WMI gelöst, demzufolge kommen diese Zeilen dem Ziele nahe:

$Filter = "Name=’$($Name)’"
$prn = Get-WMIObject Win32_Printer -Filter $Filter
$res = $prn.RenamePrinter($NewName)
#res.ReturnValue -eq 5 wenn Access Denied, bei 0 OK

Nun möchte man ja aber im Skript konkret das Cmdlet Rename-Printer nutzen, ohne jedesmal per if-Abfrage in Erfahrung zu bringen, ob das Cmdlet vorhanden ist oder ob die alternative Implementierung aufgerufen werden soll. Dazu definiert man in einem Scriptblock das fehlende Cmdlet und führt diesen über den & Call-Operator aus.

$polyfill = {Function Rename-Printer() {"Ersatz für Rename-Printer"}}
&  $polyfill

Wenn man nun unter Windows 7 versucht diesen Aufruf auszuführen passiert nichts, denn Rename-Printer wird nicht gefunden, da die definierte Funktion nur in einem reduzierten Scope zu sehen ist. Um dieses Problem zu lösen, verwendet man explizit den globalen Scope:

$polyfill = {Function Global:Rename-Printer() {"Ersatz für Rename-Printer"}}
&  $polyfill

Nach diesem Aufruf steht nun Rename-Printer zur Verfügung.

Nun gilt es nur noch obige Dinge zu kombinieren, dann erhält man folgendes Cmdlet Polyfill für Powershell um z. B. Rename-Printer nachzubauen:

# Rename-Printer geht nur unter Win8 oder höher, benötigt Admin-Rechte

if (-not (Get-Command Rename-Printer -ErrorAction SilentlyContinue)) {

# damit die Function verfügbar wird, muss sie mittels & ausgeführt werden und mit dem Scope global: versehen werden

&{

Function global:Rename-Printer ($Name, $NewName) {

$Filter = "Name=’$($Name)’"

# anstatt Name doch DeviceID?

$prn = Get-WMIObject Win32_Printer -Filter $Filter

$renres = $prn.RenamePrinter($NewName)

# renres.ReturnValue == 5 wenn Access Denied, bei 0 erfolgreich

}

}

}

Als Template kann man dieses Skelett sehen:

if (-not (Get-Command CmdletName -ErrorAction SilentlyContinue)) {
  &{ Function global:CmdletName ($Parameter) {
             # CmdletName – Nachbau
        }
    }
}

Durch Powershell Polyfills erreicht man bessere und schönere Skripte, da nur zu Beginn notwendige evtl. nicht vorhandene Cmdlets nachgebaut werden müssen. Ein Skript, welches unter Windows 8 läuft, kann somit ohne umschreiben auch direkt auf Windows 7 laufen. Selbst wenn später ein Update doch noch die Unterstützung für das betreffende Cmdlet auf Windows 7 bringen sollte, so wird automatische das dann nativ zur Verfügung stehende Cmdlet verwendet.

Drucker mittels Powershell in Windows 8.1 kopieren

30 September 2014

Leider gibt es seit Jahren unter Windows keine einfache Möglichkeit einen Drucker zu kopieren. Gemeint sind die Drucker die nach Aufruf von

Control Printers

angezeigt werden.

Dank Powershell ist dies nun unter Windows 8.1 mit den Drucker-Cmdlets  sehr einfach möglich.

Man ruft einfach

Get-Printer | Out-GridView -Title "Quelldrucker auswählen" -PassThru | foreach {Add-Printer -DriverName $_.DriverName -Name "$($_.Name) Kopie" -PortName $_.PortName}

auf und bekommt eine Auswahl der installierten Drucker angezeigt, kann den gewünschten auswählen und klickt auf OK. Man bekommt den neuen Drucker mit dem Namen des alten und dem Anhängsel Kopie angelegt.

Wie immer gibt es aber eine Ausnahme: Leider funktioniert obige Methode nicht bei Druckern die von einem anderen Rechner kommen, die also über die Variante \\Server\Freigabe angesprochen werden. Wird solch ein Drucker versucht zu kopieren, erscheint diese Fehlermeldung:

Add-Printer : Der angegebene Anschluss ist nicht vorhanden. Verwenden Sie "add-printerport", um einen neuen Anschluss hinzuzufügen, oder geben Sie einen vorhandenen
Anschluss an.
In Zeile:1 Zeichen:81
+ Get-Printer | Out-GridView -Title "Quelldrucker auswählen" -PassThru | foreach { …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (MSFT_Printer:ROOT/StandardCimv2/MSFT_Printer) [Add-Printer], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070704,Add-Printer

Wenn man man einen Drucker kopiert hat, fällt auf, dass dieser nicht unbedingt direkt zu sehen ist. In diesem Fall ist dieser Artikel interessant: https://newyear2006.wordpress.com/2014/07/09/gruppierung-bei-windows-druckern-aufheben/

Leider werden bei obiger Methode noch nicht die Einstellungen des zu kopierenden Druckers mitübertragen. D. h. die Kopie des Druckers hat immer die Standardeinstellungen, wie nach einer Neuinstallation des Druckertreibers. Dazu aber ein anderes Mal mehr…

Arbeitsweise von Powershell Desired State Configuration und Infos darüber

25 Mai 2014

Mit Powershell 4.0 hat die sogenannte Desired State Configuration (DSC) Einzug gehalten. Dabei schreibt man nicht ein Script, was wie eingerichtet werden soll, sondern man beschreibt, wie die Konfiguration eines Rechners aussehen soll. Dabei wird das laufende System von einem speziellen Prozess überwacht. Wird von diesem Prozess eine Änderung festgestellt, die nicht der gewünschten Konfiguration entspricht, kann automatisch ein Reparaturprozess gestartet werden. Dabei kann man diese Konfigurationen einfach per WSMan auf einzelne Rechner im Netz verteilen.

Hier sehr schöner Artikel, der die Vorgehensweise und vor allem auch ein paar Hintergründe beschreibt, wie die Windows Aufgabenplanung mit eingesetzt wird: http://www.verboon.info/2013/11/powershell-desire-state-configuration-my-first-experiences/

Momentan ist DSC noch nicht voll ausgereift aber die Grundlagen sind gelegt und das nötige Ökosystem entwickelt sich schnell.

Bei der Einrichtung zu beachten:

On Windows 8.1 and Windows Server 2012 R2, make certain that KB2883200 is installed or DSC will not work. On Windows Server 2008 R2, Windows 7, and Windows Server 2008, be sure to install the full Microsoft .NET Framework 4.5 package prior to installing WMF 4.0 or DSC may not work correctly.

Ein kleines eBook über DSC: https://onedrive.live.com/?cid=7F868AA697B937FE&id=7F868AA697B937FE%21110

Einführungsvideo mit Erklärungen zur Infrastruktur im Netzwerk und Einsatz mit Linux: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DCIM-B417#fbid=

Wenn man Probleme hat, hilft unter Windows:

Get-WinEvent –LogName "Microsoft-Windows-Dsc/Operational"

Windows Server 2012 (R2) Server Manager um eigene Powershell Skripte erweitern

19 Mai 2014

Seit Windows Server 2012 hat Microsoft bei den GUI-Verwaltungen der alten MMC den Kampf angesagt. Alle neuen Tools werden immer weiter in den neuen Server-Manager integriert. Führt man über das Toolsmenü einen Befehl aus, läuft im Hintergrund ein Powershell-Skript ab.

Das Toolsmenü kann man um eigene Powershell-Skripte erweitern, dazu muss man nur das Powershell-Skript in das Verzeichnis

%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Administrative Tools

verlinken. Dabei kann man auf alle im Dashboard bekannten Server zurückgreifen, indem man diese Datei ausliest:

%APPDATA%\Microsoft\Windows\ServerManager\ServerList.XML

Näheres beschreibt dieser Artikel: http://blogs.technet.com/b/keithmayer/archive/2013/11/20/step-by-step-extending-server-manager-in-windows-server-2012-and-2012-r2.aspx

Domainjoin mittels Powershell bei Small Business Server SBS

28 April 2014

Um einen Rechner mittels Powershell in eine Domäne aufzunehmen, hilft diese Zeile:

add-computer -domain domain.local -credential domain\domainadmin -oupath "OU=SBSComputers,OU=Computers,OU=MyBusiness,DC=Domain,DC=Local" –Restart

Weitere Infos zum Cmdlet gibt es hier: http://technet.microsoft.com/en-us/library/hh849798.aspx

Beim Versuch Windows Updates vom WSUS zu holen, gibts am Anfang evtl. Probleme und man bekommt eine Fehlermeldung 0x800B0001 angezeigt. Die Hintergründe sind hier schön beschrieben: http://selekta77.blogspot.de/2013/04/windows-update-fehler-800b0001-beheben.html

Wenn man aber überprüft, ob man das passende Serverzertifikat in der Computerzertifikaten hat, passt alles. Man kann also statt mit WSUS herumdoktern gleich prüfen, ob man eine Verbindung hat.

http://WSUS-SERVER/selfupdate/wuident.cab

Klappt der Download, kann man mit

wuauclt /detectnow

die Updates anschieben.

Zugriff auf WWAN Profile unter Windows 8 per Powershell

26 November 2013

Mit Windows 8.1 sind zwar nochmals einige Powershell Cmdlets hinzugekommen allerdings für WWAN, also Breitbandverbindungen wie LTE, HSDPA, UMTS und GSM war noch nichts dabei. Hier ist also Handarbeit angesagt.

Da die Windows Runtime von Windows 8 auch unter Powershell nutzbar ist, kann dort auf alle verfügbaren APIs zugegriffen werden, die für “desktop apps” gekennzeichnet sind, wie z. B. NetworkInformation: http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.connectivity.
networkinformation.aspx

Dabei sorgt der Aufruf von

[void][Windows.Networking.Connectivity.NetworkInformation,Windows, ContentType=WindowsRuntime]

dass die betreffende Assembly geladen wird, worauf dann dieser Aufruf möglich ist:

[Windows.Networking.Connectivity.NetworkInformation]:: GetConnectionProfiles()

Anstatt GetConnectionProfiles kann man auch GetInternetConnectionProfile() aufrufen, welches dann das aktuelle Internetverbindungsobjekt zurück gibt. Dieses kann man nun mittels GetConnectionCost zum NetworkCostType befragen. Die möglichen Werte sind dann hier beschrieben: http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.connectivity.networkcosttype.aspx.

Weitere Infos zu den Möglichkeiten stehen hier:

http://blogs.technet.com/b/heyscriptingguy/archive/2013/08/02/more-messing-around-with-wireless-settings-with-powershell.aspx

Wenn es Probleme genereller Natur gibt, helfen evtl. die Loggingmöglichkeiten weiter: http://msdn.microsoft.com/en-us/library/windows/hardware/dn423925(v=vs.85).aspx

Für WinRT mit Asnyc-Aufrufen und Powershell, gilt es dies zu beachten: http://rkeithhill.wordpress.com/2013/09/30/calling-winrt-async-methods-from-windows-powershell/

Alles zusammenkombiniert kann man mittels GetNetworkUsageAsync() auch herausfinden, wie viel MB pro Tag, pro Stunde, pro Minute oder insgesamt die letzten 60 Tage über die Leitung gingen!

http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.connectivity.
connectionprofile.getnetworkusageasync.aspx

Powershell 4.0 und 3.0 Versionsdurcheinander unter Windows 8.1 und Server 2012 R2

12 November 2013

Ladet man eine spezifische Powershell 3.0 Version bekommt man Version 4.0! Dieser Artikel verdeutlicht die Geschichte nochmal: http://p0w3rsh3ll.wordpress.com/2013/10/22/powershell-version-loading-on-windows-8-1-2012-r2/

Windows 8.1 Netzwerkprofil ändern von Öffentlich oder Unbekannt auf Privat, anders formuliert: Warum sehe ich meinen Drucker oder Scanner nicht?

30 Oktober 2013

Wieder mal ein tolles Thema. Ich bin entweder zu blöd oder zu alt um bei einem Windows 8.1 Gerät die Netzwerkprofilzuordnung zu ändern. Aber wahrscheinlich ist – wie immer – eher Microsoft schuld, denn seit die auf User Experience machen, wird immer alles komplizierter.

Konkret ging es darum, einen Wifi-Direct Drucker unter Windows 8.1 anzubinden. Wenn aber der Drucker nicht auftaucht, was macht man dann? Zunächst muss ich sagen, dass ich nicht wissentlich gefragt wurde, ob ich den Drucker dem öffentlichen oder privaten Netzwerkprofil zuordnen möchte. Diese Einstellung aber im Nachhinein zu ändern, ist fast unmöglich, zumindest für mich. Vielleicht hat mir mal jemand eine GUI-Anleitung.

Sei es drum, da die GUI der Mode unterliegt und dies sicher die nächsten Jahre noch mehr zunehmen wird, gilt es, das Schweizer Taschenmesser, mit Namen Powershell auszupacken.

Also zunächst die Verbindung mit dem Drucker per Wifi-Direct hergestellt. Dann als Admin eine Powershell-Eingabeaufforderung geöffnet und dann

Get-NetConnectionProfile

ausgeführt. Mit dem Ergebnis:

Name             : Netzwerk
InterfaceAlias   : Ethernet 4
InterfaceIndex   : 5
NetworkCategory  : Public
IPv4Connectivity : Internet
IPv6Connectivity : LocalNetwork

Hier kann man erkennen, dass in diesem Fall das Profil auf Public gesetzt ist. Als Admin kann man es aber ganz einfach ändern, man muss nur den Index und die gewünschte Kategorie angeben:

Set-NetConnectionProfile –InterfaceIndex 5 –NetworkCategory Private

Das wars. Nun wird der Drucker, Scanner oder was auch immer sofort erkannt und kann bei den Geräten in den Windows-Einstellungen hinzugefügt werden.

Diese Methode hat den Vorteil, sie funktioniert die nächsten 30 Jahre! Wetten?