Archive for the ‘Powershell’ Category

Wider die Arbeitsmoral

28 April 2016

Wenn man mal keinen Bock hat eine Arbeit zu Ende zu führen, warum dann nicht einfach selbstgestrickte Fehlermeldungen erzeugen?

Da sich hier vieles um Powershell dreht, hier ein Zweizeiler, welcher die Möglichkeiten schön darstellt:

Add-Type -AssemblyName System.Windows.Forms

[System.Windows.Forms.MessageBox]::Show("Das Installationsprogramm hat einen Fehler festgestellt: 0xc80003f3","Eigenständiges Windows Update-Installationsprogramm", [System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Error)

Baut man dies in ein Script ein, Profis verschlüsseln die Sache vorab, damit es nicht gar so auffällig ist, dann kann man immer sagen: Geht jetzt nicht, hab ein unlösbares Problem! Muss erst nochmal recherchieren…

Viel Spaß mit der gewonnen Freizeit!

AzureResourceManager und die Hintergründe zu Switch-AzureMode

5 März 2016

Microsofts Azure wird nicht mehr verschwinden. Wer sich effektiv mit Azure beschäftigt, der sollte wie immer per Powershell die Sache angehen. Auf GUIs kann man sich in der Regel nicht verlassen, da diese einer gewissen Mode unterliegen. Aus diesem Grund wird in diesem Blog versucht so gut wie alles per Kommandozeile bzw. Powershell zu regeln.

Blöd nur, wenn sich nun aber die Powershell Cmdlets ebenso ändern und man keinen Plan hat warum, wieso und weshalb. So liest man oft von Switch-AzureMode oder von Azure Resource Manager (ARM). Hier ein Auszug einer Microsoft Dokumentation https://azure.microsoft.com/de-de/documentation/articles/virtual-machines-deploy-rmtemplates-powershell/:

Azure PowerShell ist derzeit in zwei Versionen verfügbar: 1.0 und 0.9.8. Wenn Sie bereits Skripts haben und diese nicht sofort ändern möchten, können Sie weiterhin Version 0.9.8 verwenden. Bei der Verwendung der Version 1.0 sollten Sie Ihre Skripts sorgfältig in Präproduktionsumgebungen testen, bevor Sie sie in der Produktionsumgebung einsetzen, um unerwartete Folgen zu vermeiden.

Cmdlet-Namen der Version 1.0 haben das Muster {Verb}-AzureRm{Nomen}, während Namen der Version 0.9.8 nicht Rm enthalten (z. B. „New-AzureRmResourceGroup“ statt „New-AzureResourceGroup“). Wenn Sie Azure PowerShell 0.9.8 verwenden, müssen Sie zunächst den Ressourcen-Manager-Modus aktivieren, indem Sie den Befehl Switch-AzureMode AzureResourceManager ausführen. Dieser Befehl ist in 1.0 nicht erforderlich.

Das ist alles schön und gut, aber das Web ist voll von alten Beispielen und Code-Snippets und manchmal wäre es ganz gut tiefergehende Infos zum Thema zu erhalten.

Mittlerweile wird auf einen speziellen Artikel verwiesen, der die neuen Möglichkeiten des Ressourcen-Manager-Model anschaulich darlegt: https://azure.microsoft.com/de-de/documentation/articles/resource-manager-deployment-model/

Wenn man zum Thema etwas recherchiert, dann kann man diesen Wiki-Eintrag in Github finden, der geht sehr ausführlich nochmal auf die Hintergrunde ein: https://github.com/Azure/azure-powershell/wiki/Deprecation-of-Switch-AzureMode-in-Azure-PowerShell

Es gibt sogar ein Script, welches automatisch virtuelle Maschinen vom Azure Service Management (ASM) Modell ins Azure Resource Mangement (ARM) Model migriert: https://github.com/fullscale180/asm2arm.

Unicodezeichen in Powershell benutzen bzw. die Suche nach dem Daumen nach oben

8 Februar 2016

Möchte man bestimmte Zeichen in Powershell benutzen, die nicht direkt per Tastatur verfügbar sind, kann man den Datentyp [char] benutzen.

So erhält man z. B. durch Eingabe von

[char]0x2122

das Trademark-Symbol ™. Soweit so gut. Schwieriger wird es aber mit Zeichen, welche nicht direkt als Unicode zur Verfügung stehen.

Da gibt es z. B. den Daumen nach oben. Laut dieser Seite http://www.iemoji.com/view/emoji/56/people/thumbs-up-sign wäre der Code 0xd83ddc4d als UTF-16 also Unicode. Allerdings erhält dabei:

[char]0xd83ddc4d
Der Wert "-667034547" kann nicht in den Typ "System.Char" konvertiert werden. Fehler: "Der Wert für ein Zeichen war zu groß oder
zu klein."
In Zeile:1 Zeichen:1
+ [char]0xd83ddc4d
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastIConvertible

Was kann man tun? Nun die Tabelle bei der Webseite bietet noch UTF-32 an. Und UTF-32 kann man so benutzen:

[char]::ConvertFromUtf32(0x1f44d)

und erhält dafür!

Daraus kann man dann Konstrukte basteln wie dieses:

"Ich finde das gut $([char]::ConvertFromUtf32(0x1f44d))"

Was “Ich finde das gut ” ergibt.

Wenn es trotz allem nicht klappen sollte, hilft dieser Artikel noch weiter: https://mnaoumov.wordpress.com/2014/06/14/unicode-literals-in-powershell/

Der Herausgeber der Treibersoftware konnte nicht überprüft werden

31 Januar 2016

Hat mich doch gerade bei Windows 10 ein unverhofftes Update erreicht. Auf einmal steht da ein Fenster mit rotem Rahmen.

[Windows-Sicherheit]
—–
Der Herausgeber der Treibersoftware konnte nicht überprüft werden.

Diese Treibersoftware nicht installieren
Sie sollten auf der Website des betreffenden Herstellers nach aktualisierter Treibersoftware für das Gerät suchen.

Diese Treibersoftware trotzdem installieren
Installieren Sie nur Treibersoftware, die Sie von der Website oder einem Datenträger des Herstellers erhalten haben. Nicht signierte Software aus anderen Quellen kann Schäden auf dem Computer verursachen oder zum Verlust bzw. Diebstahl von Informationen führen.
—–
Details einblenden

Schön so was, da schrillen gleich alle Alarmglocken. Denn ich hatte kein Update angefordert. Hier findet man eine Erklärung, wann so ein Fenster auftaucht, wenn z. B. das Authenticode Zertifikat abgelaufen ist: https://technet.microsoft.com/en-us/windows/ff547534.

Und überhaupt welches Programm bzw. Treiber sollte hier aktualisiert werden?

Man kann nun mittels Process-Explorer von Sysinternals herausfinden, welches Programm da etwas zu installieren versucht aber mit Powershell geht das mit Bordmitteln fast genauso schnell. Mittels

gwmi Win32_Process –Filter "Name=’DrvInst.EXE’"| select Commandline | fl *

wird dann dann die Kommandozeile des Treiberinstallationsprogramms (DrvInst.EXE) abgefragt. Im aktuellen Fall stand da unter anderem etwas von “C:\Program Files\Synaptics\SynFP\…”. Es steht noch mehr dran aber es hat gereicht das betreffende Programm bzw. den Treiber ausfindig zu machen.

In diesem Fall war es der “Synaptics Fingerprint Reader”-Treiber. Sehr dubios, warum will der sich einfach so aktualisieren? Will da jemand meinen Fingerabdruck…

Davon unabhängig ist es ein absolutes Armutszeugnis von Microsoft, dass man immer wieder mit Sicherheitsdialogen gequält wird, die Null Aussagekraft haben und nicht mal dem erfahrenen Benutzer eine Entscheidungsinformation an die Hand geben. Alles sehr traurig.

Icons aus Dateien bzw. Icons zu Dateitypen per Powershell extrahieren

19 Januar 2016

Für diese Aufgabe brauchte man seither spezielle Programme, nun kann man Icons auch per Powershell extrahieren.

Hier ein Script um Icons aus .EXE, .DLL, generell aus Resourcedateien zu extrahieren: https://gallery.technet.microsoft.com/scriptcenter/Export-Icon-from-DLL-and-9d309047

und hier die Variante und von Dateitypen das zugehörige Icon zu erhalten: http://learn-powershell.net/2016/01/18/getting-the-icon-from-a-file-using-powershell/

Mittels Powershell geladene DLL-Dateien aus einem Prozess auslesen

4 Januar 2016

Öffnet man unter Windows die Eingabeaufforderung, so kann man mit TASKLIST.EXE die aktuell ausgeführten Programme bzw. Prozesse auflisten. Bei den Optionen kann man /M angeben, dann werden zu jedem Prozess die geladenen DLL-Dateien angezeigt.

Hier ein Beispiel von Windows 8.1:

tasklist /FI "imagename eq cmd.exe" /M

Abbildname                     PID Module
========================= ======== ============================================
cmd.exe                      15872 ntdll.dll, KERNEL32.DLL, KERNELBASE.dll,
                                   msvcrt.dll, winbrand.dll

Nun ist es wie immer schwierig von einer Textausgabe die Daten weiterzuverarbeiten. Aber es gibt ja Powershell und das äquivalente Kommando in Powershell sieht so aus:

Get-CimInstance -ClassName Win32_Process -Filter "Name=’cmd.exe’" | Get-CimAssociatedInstance -Association Cim_ProcessExecutable | ft name

die Ausgabe sieht dann so aus:

name
—-
c:\windows\system32\cmd.exe
c:\windows\system32\ntdll.dll
c:\windows\system32\kernel32.dll
c:\windows\system32\kernelbase.dll
c:\windows\system32\msvcrt.dll
c:\windows\system32\winbrand.dll

da es aber nun Objekte sind, kann man natürlich auch mehr Infos anfordern:

Get-CimInstance -ClassName Win32_Process -Filter "Name=’cmd.exe’" | Get-CimAssociatedInstance -Association Cim_ProcessExecutable | ft name, version

name                               version
—-                               ——-
c:\windows\system32\cmd.exe        6.3.9600.17415
c:\windows\system32\ntdll.dll      6.3.9600.17736
c:\windows\system32\kernel32.dll   6.3.9600.17415
c:\windows\system32\kernelbase.dll 6.3.9600.17415
c:\windows\system32\msvcrt.dll     7.0.9600.17415
c:\windows\system32\winbrand.dll   6.3.9600.17415

Mit etwas Aufwand kann man sich auch einen Prozessbaum bauen: https://p0w3rsh3ll.wordpress.com/2012/10/12/show-processtree/

Mittels Get-CimAssociatedInstance kann man sowieso noch jede Menge interessante Dinge in Erfahrung bringen, z. B. wer angemeldet ist, welche Partitionen ein Laufwerk enthält usw. http://csharpening.net/?p=876.

OpenSSH-Unterstützung von Windows

14 Dezember 2015

Microsoft hat sich ja mittlerweile auch zu OpenSSH bekannt und entwickelt dazu einen Windows Port: http://blogs.msdn.com/b/powershell/archive/2015/10/19/openssh-for-windows-update.aspx. Leider fehlt noch einiges, vor allem ein passender SSH-Powershell Client.

Man kann zwar über ein separates Modul nachhelfen, wie hier beschrieben http://www.powershelladmin.com/wiki/SSH_from_PowerShell_using_the_SSH.NET_library, dieses Modul setzt auf diese Library auf http://sshnet.codeplex.com/, doch leider klappt das noch nicht so toll.

Wenn es generell nicht funktioniert, muss man mittels Add-Type –Path .\Renci.SshNet.dll laden. Außerdem ist die Handhabung, vor allem von Enter-SSHSession alles andere als intuitiv. Aber zur Not klappts.

Hier noch ein paar weitere Infos: http://www.jonathanmedd.net/2013/08/using-ssh-to-access-linux-servers-in-powershell.html.

Was gibt der Registrierungsschlüssel DHCPGatewayHardware her? Oder – wie kann man alternativ per Powershell das DHCP-IPv4-Gateway ermitteln?

28 September 2015

Hier mal etwas für Forensiker. Aus der Not geboren, dass nur eine Fernwartung beim Kunden möglich war – die nur einmal aufgebaut werden konnte, galt es herauszufinden, warum Netzprobleme bei der IPv4-Adressvergabe auftraten. Eigentlich sollten die Clientrechner IP-Adressen im Bereich 192.168.0.X bekommen aber effektiv bekamen fast alle Rechner eine im Bereich 192.168.1.X. Dadurch war kein Internetzugang mehr möglich und auch der Fileserver unter 192.168.0.1 war nicht mehr erreichbar. Da im konkreten Fall ein Speedport mit der Adresse 192.168.0.100 der DHCP-Server war, wurde zunächst eine Station mit einer fixen IP-Adresse im Bereich des Speedport versehen. Von dort aus war dann der Zugriff zum Speedport möglich. Auch das Internet mit einer Fernwartungssitzung klappte dadurch wieder. Jetzt galt es aber rauszubekommen, warum die Rechner teilweise falsche IP-Adresse bekamen. Nur wie macht man das, wenn man auf der einzigen Netzwerkkarte per Fernwartung aufgeschaltet ist?

Zunächst versuchte ich Scapy per Python ans laufen zu bekommen,  um dieses Script ausführen zu können: https://bitbucket.org/secdev/scapy/wiki/doc/IdentifyingRogueDHCPServers. Die Idee war ganz einfach einen Netzwerkmitschnitt über DHCP-Server-Ankündigungen zu machen. Aber leider beschwerte sich Scapy, beim Versuch der Installation, ständig über eine weitere, fehlende Abhängigkeit. Am Ende lief es auf jeden Fall nicht.

Wireshark wäre noch eine Option gewesen, da die WinPCap-Treiber wegen Scapy eh schon installiert waren. Aber Wireshark kann jeder.

Wie immer wäre mir eine Powershell-Lösung die liebste, aber leider gibt es noch nichts Vergleichbares zu Scapy. Bei der Suche nach der Powershell-Lösung bin ich allerdings über diesen Artikel gestolpert: http://www.ingmarverheij.com/read-dhcp-options-received-by-the-client/. Ich hatte zwar beim betreffenden Windows 7 Rechner keinen Eintrag mit DhcpInterfaceOptions aber zumindest der Eintrag DhcpGatewayHardware war vorhanden. Der Eintrag war als REG_BINARY mit dem Wert

c0 a8 01 01 06 00 00 00 e8 fc af ab c0 24

eingetragen. Der Wert von DhcpGatewayHardware ist zu finden unter HKLM\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\{GUID}.

Per Powershell erreicht man den Wert über

$a = gwmi Win32_NetworkadapterConfiguration
$i = $a | where {$_.Description –like "*Intel*"}

$i.SettingID

$si = $i.SettingID

$ri = Get-ItemProperty -path "registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\$si" -name dhcpgatewayhardware | select DHCPGatewayHardware

$ri

Bei *Intel* sollte man den Hersteller seiner Netzwerkarte eintragen, für Realtek z. B. *Realt*, wenn es mehrere geben sollte, muss natürlich die betreffende herausgefiltert werden. Das entscheidende dabei ist, dass man die GUID der SettingID bekommt, über welche man weiß wo man in der Registrierung bei den Interfaces suchen muss.

Auf jeden Fall bekommt man am Ende bei $ri z. B.  diese Ausgabe:

DhcpGatewayHardware
——————-
{192, 168, 1, 1…}

Man sieht bereits, dies ist der falsche Wert, der am Anfang dafür gesorgt hatte, dass der Kunde nicht arbeiten konnte. Das interessante dabei ist, 192.168.1.1 entspricht hexadezimal genau “c0 a8 01 01”, die grüne Markierung verdeutlicht nochmal den Zusammenhang. Also ist der Zusammenhang schon mal hergestellt. Der hintere Wert e8 fc af ab c0 24 sieht wie eine MAC-Adresse aus, denn warum sonst sollte Microsoft den Eintrag DhcpGatewayHardware nennen?

Also noch die Bytes 8-14 ausgelesen und daraus eine MAC-Adresse gebastelt:

$mac=$ri.DhcpGatewayHardware[8..14]
$mac=$mac| foreach {$new=""} {$new+="{0:x02}:" -f $_} {$new}
$mac=$mac.TrimEnd(":")

$mac

Nun hat man in $mac die MAC-Adresse des DHCP-Servers, welcher die IP-Adresse 192.168.1.1 geliefert hatte.

Also mal Google bemüht und dies gefunden: http://macaddress.webwat.ch/hwaddr/E8:FC:AF. Hier wird E8:FC:AF Netgear zugeordnet:

Device mac address: E8:FC:AF
Base16 encoding: E8FCAF
producer name: NETGEAR INC.,

producer address:

350 EAST PLUMERIA DRIVE
SAN JOSE CALIFORNIA 95134
UNITED STATES

Jetzt galt es nur noch ein Gerät ausfindig zu machen. Aber mit dem Wissen, dass es sich um ein Netgear Gerät handelte, war der weitere Weg wesentlich einfacher, als wenn es irgendein Gerät im Netz gewesen wäre. Vor allem war dadurch auch klar, dass es sich nicht um einen gefakten bzw. Rogue-DHCP-Server handelte, welcher eine Attacke im Netz ritt.

Übrigens: Bei einem korrekt konfigurierten und funktionierendem Netz bekommt man, bei Anwendung obigen Scripts, einfach das Gateway mit der betreffenden MAC-Adresse, wenn DHCP aktiviert ist.

Suchen und Ersetzen in Verknüpfungen (.LNK-, .URL- und .WebSite-Dateien) auf dem Desktop automatisieren

20 September 2015

Angenommen, man hat einen üblichen Desktop vor sich. Dieser ist mit zig Dateien und Verknüpfungen übersäht. Wenn man dann wissen möchte, welcher Link auf ein bestimmtes Verzeichnis verweist, dann kann das schnell in Arbeit ausarten. Wenn man dann noch etwas ersetzen muss, kann man in vielen Umgebungen Spaß mit fehlender UAC Unterstützung unter Windows haben. Am Ende flucht man, warum man nicht mal mit Admin-Rechten einen einfachen Link aktualisieren kann.

In allen diesen Fällen hilft wie immer Omo, nö Powershell wars.

Zunächst gilt es alle Verknüpfungen auf dem Desktop zu finden. Man erzeugt zunächst ein Shell-Objekt:

$shell = New-Object –ComObject Shell.Application

Nun benötigt man die Links vom Desktop. Man könnte nun direkt auf den Pfad des aktuellen Benutzers verweisen aber noch eleganter ist es, sich vom System den Pfad geben zu lassen:

$desktop = $shell.Namespace(0x10)

Wenn man sich $desktop anschaut erhält man:

Title                      : Desktop
Application                : System.__ComObject
Parent                     :
ParentFolder               : System.__ComObject
Self                       : System.__ComObject
OfflineStatus              :
HaveToShowWebViewBarricade : False
ShowWebViewBarricade       : False

Nicht sehr überzeugend oder? Besser wird es damit:

PS > $desktop.Self

Application  : System.__ComObject
Parent       : System.__ComObject
Name         : Desktop
Path         : C:\Users\Benutzer\Desktop
GetLink      :
GetFolder    : System.__ComObject
IsLink       : False
IsFolder     : True
IsFileSystem : True
IsBrowsable  : False
ModifyDate   : 17.09.2015 17:31:32
Size         : 0
Type         : Dateiordner

Man bekommt also mittels $desktop.Self.Path den aktuellen Pfad zum Desktop. Damit kann man nun etwas anfangen, z. B. die Verknüpfungen ermitteln:

Get-ChildItem $desktop.Self.Path -Filter *.lnk

Aber Moment, wer sich vielleicht wundert, warum nicht alle Verknüpfungen auftauchen, die ein Benutzer auf seinem Desktop hat, dem sei gesagt, es gibt auch einen öffentlichen Desktop, der für alle Benutzer gilt. Obiger Namespaceaufruf hatte nur den Desktop des aktuellen Benutzers zurückgegeben. Die öffentliche Variante erhält man so:

$publicDesktop = $shell.Namespace(0x19)

wenn man sich hier $publicDesktop.Self.Path anschaut erhält man

C:\Users\Public\Desktop

Kurz noch als Erklärung zu 0x10 bzw. 0x19, dabei handelt es sich um Konstanten aus den Shell Special Folders, eine Auflistung ist hier zu finden: https://msdn.microsoft.com/en-us/library/windows/desktop/bb774096(v=vs.85).aspx. Da es wie immer eine Tortur ist, eine aktuelle Beschreibung in der MSDN zu finden, sei noch diese Methode genannt, um alle möglichen Werte zu sehen:

0..250| % { $v=($shell.NameSpace($_)).Self; if ($v -ne $null) { New-Object psObject -Property @{Index=$_; Name=$v.Name; Path=$v.Path}} }

Weiter beim eigentlichen Thema. Nun wird es langsam was, so bekommt man beides zusammen:

$dl = Get-ChildItem $desktop.Self.Path -Filter *.lnk
$dl += Get-ChildItem $publicDesktop.Self.Path -Filter *.lnk

Nun enthält $dl tatsächlich alle LNK-Dateiverweise. Jetzt also zum Inhalt der Verknüpfungen. Da LNK-Dateien ein eigenwilliges Binärformat haben, muss dieses speziell gelesen werden. Aber die Shell-Klassen bieten hier auch Unterstützung. Dazu gibt es die Methode ParseName, welche so angewendet werden kann:

$fileItem = $desktop.ParseName($dl[0].Name)
$fileItem.IsLink

Erst jetzt weiß man, ob die LNK-Datei wirklich eine Linkdatei ist. Wenn dem so ist, kann man hiermit das Link-Objekt instanzieren:

$sc = $fileItem.GetLink

$sc enthält, dann z. B. Daten wie diese:

Path             : C:\Windows\SysWOW64\cmd.exe
Description      :
WorkingDirectory : C:\windows\SysWOW64
Arguments        :
Hotkey           : 0
ShowCommand      : 1
Target           : System.__ComObject

Hier kann man nun konkret auch den Pfad oder das Working-Directory ändern. So kann man z. B. im obigen Beispiel den Pfad von SysWOW64 in System32 ändern, welches dann so aussieht:

$sc.Path = $sc.Path.Replace("SysWOW64", "System32")

Damit diese Änderung aber tatsächlich auch auf der Platte landet, muss die Änderung noch gespeichert werden:

$sc.Save

Leider hat die bisherige Vorgehensweise ein paar Probleme. Denn das obige Zusammenführen des User- und des Öffentlichen-Desktop, macht Probleme. denn ParseName verlangt immer den reinen Dateinamen ohne Pfad, was dann bei Anwendung obiger Methode bei öffentlichen Desktopobjekten beim Aufruf über $desktop nicht zum Ziel führt. Man sollte also $dl nach dem Pfad abfragen und entsprechend $desktop oder $publicDesktop verwenden.

if ($_.DirectoryName –eq $desktop.Self.Path) {
  $fi = $desktop.ParseName($_)
} else {
  $fi = $publicDesktop.ParseName($_)
}

Somit hat man nun in $fi immer das richtige FileItem und kann so weiterverfahren:

if ($fi.IsLink) {
  $sc = $fi.GetLink
  $sc.Path = $sc.Path.Replace("ALT", "NEU")
  $sc.Save

}

Übrigens kann man nicht nur LNK-Dateien sondern auch .URL und .WebSite –Dateien damit bearbeiten, welche etwas abgewandelte Link-Dateien sind. Von der Verarbeitung jedoch ändert sich nichts, man geht direkt auf die Pfad-Eigenschaft los und ändert diese.

So da es nun wie so oft etwas unübersichtlich wurde, alles nochmal geballt, inkl. .URL und .WEBSITE:

$shell = New-Object –ComObject Shell.Application
$desktop = $shell.Namespace(0x10)
$publicDesktop = $shell.Namespace(0x19)
$dl = Get-ChildItem $desktop.Self.Path -Filter *.lnk
$dl += Get-ChildItem $desktop.Self.Path -Filter *.url
$dl += Get-ChildItem $desktop.Self.Path -Filter *.website
$dl += Get-ChildItem $publicDesktop.Self.Path -Filter *.lnk
$dl += Get-ChildItem $publicDesktop.Self.Path -Filter *.url
$dl += Get-ChildItem $publicDesktop.Self.Path -Filter *.website
$dl | foreach {
    if ($_.DirectoryName –eq $desktop.Self.Path) {
         $fi = $desktop.ParseName($_.Name)
    } else {
         $fi = $publicDesktop.ParseName($_.Name)
    }
    if ($fi.IsLink) {
       $sc = $fi.GetLink
       $sc.Path = $sc.Path.Replace("ALT", "NEU")
       $sc.Save()
    }
}

Falls man eine Fehlermeldung wie z. B. diese bekommt

Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In Zeile:21 Zeichen:8
+        $sc.Path = $sc.Path.Replace("ALT", "NEU")
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

sollte man sich überlegen, das Script vielleicht als Admin auszuführen, denn es ist nicht so gern gesehen, wenn einfache Benutzer den Öffentlichen Desktop verändern!

CHKDSK Ergebnisse per Powershell auslesen

17 September 2015

Wenn man ChkDsk auf Laufwerk C: eines Windows Rechners anwendet, wird man meist gefragt, ob man beim nächsten Neustart die Prüfung durchführen möchte. Soweit kein Problem. Nur muss man sich nach der Prüfung die passende Log-Datei heraussuchen, mit GUI mitteln wie immer mühsam, deshalb hier ein kleiner Powershell-Einzeiler, der die CHKDSK-Einträge auflistet:

Get-WinEvent -FilterHashtable @{logname="Application"; id="1001"}| where providername -eq Microsoft-Windows-WinInit | fl *

Wer sich für die vergangenen Prüfungen interessiert, der wird wahrscheinlich eher im “System Volume Information”-Verzeichnis, dort speziell im Chkdsk-Verzeichnis fündig. Dort gibt es z. B.

Chkdsk20150917130104.log

welche man sich per Powershell mittels

Get-Content .\Chkdsk20150917130104.log -Encoding Unicode

anschauen kann.

Um auf System Volume Information zugreifen zu können, benötigt man allerdings spezielle Rechte! Näheres hier: https://support.microsoft.com/en-us/kb/309531. Davon die Kurzfassung als Admin:

icacls "C:\System Volume Information" /E /G Admin:F

Wer sich für die reine Powershellfassung für ICACLS interessiert, wird hier fündig: http://blogs.technet.com/b/josebda/archive/2010/11/09/how-to-handle-ntfs-folder-permissions-security-descriptors-and-acls-in-powershell.aspx sowie http://blogs.msdn.com/b/johan/archive/2008/10/01/powershell-editing-permissions-on-a-file-or-folder.aspx.

Für was das “System Volume Information”-Verzeichnis alles herhalten muss: http://blogs.msdn.com/b/oldnewthing/archive/2003/11/20/55764.aspx.


Folgen

Erhalte jeden neuen Beitrag in deinen Posteingang.