FAQs: PowerShell in Total Commander

English support forum

Moderators: white, Hacker, petermad, Stefan2

Post Reply
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

FAQs: PowerShell in Total Commander

Post by *Stefan2 »

Eigene Befehle mit der PowerShell


viewtopic.php?t=48072

würde ich gerne einen Button setzen, der den Dialog "Attribute ändern" mit einer gespeicherten Vorgabe öffnet

- - -

Hi Ingo, das kann doch schon dein Betriebssystem, und die Befehle kannst du in TC einbetten/aufrufen.

Öffne eine DOS-Box und schau dir mal 'attrib /?' an.

- - -

Diesen Befehl kannst du in einem Button konfigurieren,
oder ein Benutzer definierten Befehl (usercmd.ini) erstellen,
welchem du auch ein Tastaturshortcut zuweisen kannst.



Diesen Befehl würde ich mit PowerShell realisieren.

Kommando: Powershell
Parameter: Get-Content[face=garamond] '%L' [/face]| ForEach{ Attrib +S -H $_ }
Startpfad:
Icondatei: Powershell
Tooltip: Für jede markierte Datei: ändere Attribute


Blau = Powershell
Rot = TC Parameter, hier "%L" für eine temporäre Textdatei mit allen ausgewählten Dateien.
Schwarz = dein individueller Kode

Drücke F1 im Buttondialog für weitere Infos über TC Parameter wie zB "%L".
Mehr über Buttons: http://ghisler.ch/board/viewtopic.php?p=287965#287965
Mehr über Benutzerbefehle: http://ghisler.ch/board/viewtopic.php?p=291895#291895


- - -


Zum Beispiel kopiere dir diesen Kode und füge in in der Buttonbar ein (Kontextmenü: Einfügen)

Durch das Fragezeichen am Anfang des Parameterfeldes wird dir der Befehl
vor der Ausführung angezeigt, und du kannst die Argumente des Attrib Befehls anpassen.

Code: Select all

TOTALCMD#BAR#DATA
PowerShell -NoExit 
?Get-Content '%L' | ForEach{ Attrib +S -H $_ }
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe
PowerShell TEST - ForEach in %L


-1
- - -

Dieser Befehl bedeutet:

Get-Content '%L' | ForEach{ $_ }

- "Get-Content xxx.txt" = hole mir den Inhalt der Datei xxx.txt.
- Als Pfad zur Datei wird hier der TC-Parameter "%L" eingesetzt,
welcher auf eine temporäre Textdatei im User Temp-Ordner verweist,
in welcher alle ausgewählten Dateien, eine pro Zeile, aufgelistet sind.
(siehe TC Hilfe: %L = voller Pfad ; %F = nur Dateinamen.ext)
- "Get-Content" liest also diese temporäre Datei ein und erstellt
ein PowerShell Array, dies bedeutet im Wesendlichen: jede gelesene Zeile ist
ein eigenes Objekt, welches im folgenden ForEach-Konstrukt angesprochen wird.
- Mittels der Pipe "|" wird die Ausgabe von "Get-Content" an den nächsten
Befehl übergeben, hier: Zeile für Zeile.
- Das "ForEach-Object{....$_ ...}" verarbeitet jetzt jede Zeile,
hier durch das "$_" repräsentiert, und man kann da irgendetwas damit erledigen,
wie hier zB den DOS-Befehl "Attrib +S -H" auf jede ausgewählte Datei (Textzeile von %L) anwenden.



Test-Button, welcher nur die ausgewählten Dateien als Text ausgibt:

Kommando: Powershell
Parameter: Get-Content[face=garamond] '%L' [/face]| ForEach{ """Zeile: $_ """ }
Startpfad:
Icondatei: Powershell
Tooltip: Für jede markierte Datei: ändere Attribute


Oder ein simpleres Beispiel:
Get-Content '%L' | ForEach{ $_ }


Bitte bedenke, dass wir hier nur einen Text aus einer Textdatei verwenden!
Befehle, welche mit dem reinen Namen etwas anfangen können, funktionieren damit prima.
Aber wir können keine Eigenschaften der ausgewählten Datei verwenden, da diese im Text nicht enthalten sind.
Wir können aber mittel "Get-Item xxx.txt", oder hier: "Get-Item $_ aktuelle Zeile / Objekt"
eine Verbindung zum realen Objekt herstellen (VBScript: Set oFile = FSO.GetFile(vFullName))

Get-Item:
Get-Content '%L' | ForEach{ (GI $_).BaseName }
Get-Content '%L' | ForEach{ $Obj=(GI $_); $obj.BaseName; $obj.LastWriteTime }


- - -

Hier eine kurze Zusammenfassung bezüglich der "PowerShell" in TC



Die PowerShell 2.0 gehört zum Lieferumfang von Windows 7; in Windows 8 ist die neuere Version 3.0 enthalten.
Bei Windows 8.1 wurde PowerShell Version 4 mitgeliefert, bei Windows 10 die PowerShell Version 5.
Neuere versionen können kostenlos bei Microsoft heruntergeladen werden.
PowerShell ist Bestandteil des "Windows Management Framework", wozu auch die jeweilige .NET Framework Version gehört.

Für das Arbeiten mit Dateien ist die PoSh v3 vollkommen ausreichend, die Neuerungen von v4 und v5 werden nicht benötigt.
Neuerungen der PowerShell 5.0: http://www.searchdatacenter.de/tipp/Aeltere-PowerShell-Versionen-auf-die-PowerShell-50-aktualisieren

Installieren von Windows PowerShell
https://msdn.microsoft.com/de-de/powershell/scripting/setup/installing-windows-powershell



Ein Befehl oder Skript funktioniert nicht?
Jede PowerShell-Version bringt neue Befehle (cmdlets) und teilweise Verbesserungen mit.
Sollte ein im Forum gefundener Code bei dir nicht funktionieren, so wurde der Code
eventuell mit einer neueren PS-Version geschrieben, als die welche du installiert hast.
Wenn du die Fehlermeldung kopierst und im Forum postest, kann man dir sicherlich helfen.
So kennt zB Get-ChildItem die Parameter " -File" und " -Directory" erst ab Version PSv3.


Zu Testzwecken wird auch oft die PowerShell.exe mit dem Parameter " -NoExit" aufgerufen,
damit sich die Konsole nicht gleich wieder schließt. Entferne " -NoExit" wenn du das nicht mehr benötigst.

Des Weiteren kann man an viele Befehle ein " -WhatIf" anhängen, um den Befehl nur zu simulieren
und als Text auszugeben, anstatt ihn gleich auf die Dateien los zu lassen. Lese die Textausgabe, und
wenn diese das ausgibt, was du erwartest, entferne das " -WhatIf" um den Befehl "scharf" zu machen.

Manche Befehle wurden auch ohne -WhatIf als Nur-Text-Ausgabe geschrieben, um etwas aus zu testen.
Hier muss der komplette Befehl etwas umgeschrieben werden, damit er tatsächlich funktioniert.
Probiere den Test-Code erst mal aus und gib Feedback im Forum, um den "scharfen" Code zu erhalten.

Sollte der Code mit RegEx (ReExp/RE/Regular Expressions/Reguläre Ausdrücke) arbeiten,
so ist dieser meist exakt auf deine geposteten Beispiele zu geschnitten und kann oft nicht Eins-zu-Eins
auf andere Beispiele und Problemstellungen übernommen werden. Hier musst du noch mal nachfragen.


Falls ihr ein PowerShell-Skript (Test.ps1) aus einer DOS-Box starten wollt,
müsste Ihr den Interpreter PowerShell vorne dran schreiben (powershell Test.ps1 <ENTER>)
oder erst mal komplett zu PowerShell wechseln (powershell <ENTER> Test.ps1 <ENTER>)
Auf jeden Fall müsst ihr beachten, das PowerShell nur Skripte ausführt,
bei dehnen der komplette Pfad mit angegeben wurde ( C:\Temp\PSTest\Test.ps1 <ENTER>)
Hier funktioniert aber auch eine relative Pfadangabe, falls man
sich bereits im Ordner mit dem Skript befindet ( .\Test.ps1 <ENTER>)
Tipp: anfangen den Namen des Skriptes zu schreiben, und dann die TAB-Taste drücken,
dann macht PS das von sich aus (Tes <TAB> >>> .\Test.ps1 <ENTER>)




PowerShell Befehle
Siehe zur Info über die Befehle:
https://ss64.com/ps/
https://de.wikipedia.org/wiki/PowerShell
Siehe auch unten bei "Weiterführende Infos"


PowerShell Befehle werden Cmdlets (Command'lets) genannt.
Standardmäßig werden sie in der Form "Tunwort/Befehl" - "Minuszeichen" - "Hauptwort/Ziel" benannt.
Beispiel:
WasTun-MitWas
Get-Process
Write-Host
New-Item
Remove-Item
Standardmäßig wird der Begriff in der "Einzahl "-Form benannt, zB nicht get-processES oder new-itemS

Siehe auch unten bei "Liste aller verfügbaren cmdlets"


Für viele Cmdlets existieren bereits Aliase, um die Befehle zur Verwendung in der Kommandozeile abzukürzen:
Beispiel:
Get-Process gps ps
New-Item ni
Remove-Item del erase rd rm rmdir
Copy-Item copy cpi cp
Rename-Item rni ren
In einem Skript sollte der volle Name verwendet werden, um die Lesbarkeit zu erhalten.

Siehe auch unten bei "Liste aller Aliase"



PowerShell-Skripte ausführen

Starte die PowerShell-Konsole
Rufe mittels "Windows-Taste + R" das "Ausführen"-Fenster auf und gib dort den folgenden Befehl ein:
powershell <ENTER>

Mittels des Befehls "cd" kann man den Ort (Pfad, Ordner, Verzeichnis) wechseln.
Verwende dabei die TAB-Taste, um dir die Pfade, welche du gerade angefangen hast zu tippen, zu vervollständigen.
CD C.\win <TAB> >>> C:\Windows

Um Laufwerke zu wechseln, tippe den Laufwerksbuchstaben, gefolgt von einem Doppelpunkt und <ENTER>
X: <ENETR>


Tipp: lass dir TC eine DOS-Box im aktuellem Ordner öffnen, und starte darin die PoSh:
TC-Menü "Befehle > Kommandozeilenfenster öffnen"
powershell <ENTER>


Du kannst auch einen Button anlegen, um die PoSh direkt im aktuellen Ordner zu starten:
Kommando: PowerShell -NoProfile -NoExit
Parameter:
Startpfad:
Icondatei: powershell
Tooltip: Start PowerShell Box



Ausführen von PowerShell-Skripten, Befehlen, Einzeiler
In die PowerShell-Konsole (das schwarze Fenster) kann man beliebigen Kode einfügen und ausführen.
Dies gilt auch, wenn der Einzeiler in einem TC-Button oder Benutzerbefehl geschrieben wird.


Einzeiler
Komplettes Skript in einer einzigen, ggf. sehr langen Zeile.

Kommando: PowerShell -NoExit
Parameter: Get-Content '%L' | ForEach{$i=0}{ $I++; """Zeile $i : $_ """}


Meist unter Verwendung von Aliasen, Abkürzungen und sehr kurzen Variablennamen sowie weglassen von Leerzeichen.
Achtung: Lange "Einzeiler" können im Forum am Seitenrand auf mehrere Zeilen umgebrochen sein.
dir|%{$s=0}{"NAME: $_";"BASE: "+$_.BaseName;$s+=$_.length}{"Gesamtgröße: $s"}

Guter Stil sollte sein, zu "Schulungszwecken" bzw. zum Verständnis, zusätzlich ein ausführliches Skript
darunter zu stellen, oder das kurze Skript etwas zu erklären.
Get-ChildItem | ForEach-Object{ $size=0 }{ "NAME: $_" ; "BASE: " + $_.BaseName ; $size+=$_.length }{ "Gesamtgröße: $size" }


Mehrzeiler / Skripte
Sind größere Skripte, bei dehnen die Befehle am Pipe-Symbol "|" oder einem Semikolon ";"
in mehrere Zeilen umgebrochen sind, oder einfach aus mehreren Einzelzeilen (Befehlen) bestehen.
Diese werden am Besten in eine SkriptDATEI mit *.ps1 Erweiterung geschrieben.

Kommando: PowerShell -NoProfile -NoExit -ExecutionPolicy Bypass -File "%COMMANDER_PATH%\TOOLs\CMDs\Mein Skript.ps1"
Parameter:
(Kein Problem mit %- und Leerzeichen/Quoting im Kommando-Feld)


Bei PowerShell kann man solche Mehrzeiler aber auch einfach in die PowerShell-Konsole rein kopieren.
Die Konsole wird dann diese zwei ">>" Zeichen anzeigt.
Beende diese Eingabe mit einer leeren ">>" Zeile plus <ENTER>

Get-ChildItem |
ForEach-Object{ $size=0 }{
"NAME: $_"
"BASE: " + $_.BaseName
$size+=$_.length
}
{
"Gesamtgröße: $size"
}



Start von PowerShell-Skriptdateien (*.ps1)

Kommando: PowerShell -NoProfile -NoExit -ExecutionPolicy Bypass -File "%COMMANDER_PATH%\TOOLs\CMDs\Mein Skript.ps1"
Parameter:

Falls man den Code in eine Textdatei mit ".ps1" Endung schreibt, so kann diese Skriptdatei NICHT
einfach so ausgeführt werden. Das verhindern die Sicherheitsmechanismen der PowerShell.
Dies gilt auch, wenn die Skriptdatei aus einem TC-Button oder Benutzerbefehl aus aufruft.

.\test.ps1 : File C:\Temp\test.ps1 cannot be loaded because running scripts is
disabled on this system. For more information, see about_Execution_Policies at
http://go.microsoft.com/fwlink/?LinkID=135170.


Hier muss jeder sein PowerShell zuerst mitteilen, welche Skriptdateien ausgeführt werden dürfen.
Dies geschiet durch das setzen Einer von vier unterschiedliche Ausführungsrichtlinien:
-- Restricted: Der Standard, ALLE Skriptdateien sind blockiert.
-- Allsigned: Nur Skripte, die eine digitale Signatur aufweisen, werden ausgeführt.
-- Remotesigned: Kurz gesagt: lokale Skripte werden ausgeführt, heruntergeladene nicht.
("heruntergeladene" bedeutet: komplett heruntergeladene SkriptDATEIEN. Von Webseiten kopierter
Text, in lokal erstellten Textdateien eingefügt, gelten als lokal)
-- Unrestricted: ignoriert Signaturen, frägt aber nach, bei heruntergeladenen Dateien.

Damit Skriptdateien ausgeführt werden, setze dein PowerShell auf "Remotesigned".
Verwende dazu diesen Befehl in der PowerShell-Konsole:
Set-ExecutionPolicy Remotesigned

Damit wir das nicht jedesmal erklären müssen, lassen wir euch die PowerShell mit einer temporären Policy starten
"PowerShell.exe -ExecutionPolicy Bypass", dann könnt ihr ebenfalls das Skript ausführen.


- - -

Parameter der PowerShell.exe

PowerShell.exe
PowerShell -NoExit
PowerShell -NoProfile -NoExit -ExecutionPolicy Bypass -File "%COMMANDER_PATH%\TOOLs\CMDs\Mein Skript.ps1"
PowerShell -NoProfile -NoExit -ExecutionPolicy Bypass -Command "& {& 'C:\Temp\PS Skripte TEST\ShellScript.ps1' Arg1 Arg2}"


Eigentlich reicht als Kommando das Wort "Powershell" aus. (HILFE: PS > Powershell.exe /?)

Wenn du möchtest, dass dein PoSh-Profil geladen wird, entferne "-NoProfile" (HILFE: PS > help about_Profiles).

Wenn bei dir die Skriptausführung erlaubt ist (HILFE: PS > help about_Execution_Policies) benötigst du "-ExecutionPolicy Bypass" nicht.
(Die "ExecutionPolicy" ist zwar nur beim Aufruf von SkriptDATEIEN nötig, nicht bei direkt eingegebenen Befehlen, ich lasse das Argument aber standardmäßig stehen)

Wenn du die Informationen in der PoSh-Konsole (das schwarze Fenster) nicht benötigst und das Fenster automatisch geschlossen werden soll, entferne "-NoExit".
Bei der ersten Skriptausführung lassen wir es gerne offen, um etwaige Fehler mitlesen zu können.



Mehr und ausführlicher zB hier nachlesen:

https://msdn.microsoft.com/de-de/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
-NoExit Nach dem Ausführen der Startbefehle erfolgt kein Beenden. (Entferne "-NoExit" um das schwarze Fenster automatisch zu schließen)
-NoLogo Blendet die Copyrightinformationen beim Start aus.
-NoProfile Das Windows PowerShell-Profil wird nicht geladen. (Deine eigene PoSh-Einstellungen werden nicht geladen / verändert)
-ExecutionPolicy Legt die Standardausführungsrichtlinie für die aktuelle Sitzung fest (Normalerweise dürfen Skripte nicht ausgeführt werden)
-Command Führt die angegebenen Befehle (samt Parametern) so aus, als wären über die Windows PowerShell-Befehlszeile eingegeben worden,
und wird dann beendet, es sei denn, der NoExit-Parameter wird angegeben.
Um eine Zeichenfolge zu schreiben, die einen Windows PowerShell-Befehl ausführt, verwenden Sie das Format: "& {<command>}"
-File [] Führt das angegebene Skript im lokalen Bereich aus, sodass die Funktionen und Variablen, die das Skript erstellt, in der aktuellen Sitzung verfügbar sind. Geben Sie den Pfad der Skriptdatei und Parameter an.
File muss der letzte Parameter im Befehl sein, da alle Zeichen, die nach dem File-Parameter eingegeben werden, als Pfad der Skriptdatei gefolgt von den Skriptparametern und ihren Werten interpretiert werden.



https://ss64.com/ps/powershell.html
-NoExit Do not exit after running startup commands. (Remove this to let the console close after run)
-NoLogo Hide the copyright banner at startup.
-NoProfile Do not use the user profile.
-ExecutionPolicy Set the default execution policy for the session. (to allow this script to run)
-Command Execute the specified commands
To write a string that runs a PowerShell command, use the format: "& {command}"
-File Execute a script file.


Argumente übergeben

Kommando: PowerShell -NoExit
Parameters: -Command "& {& 'h:\temp\Power shell Test\Test datei.ps1' Abc XXX 678}"

-oder (bei Umgebungsvariablen und Leerzeichen)-
Kommando: PowerShell -NoExit -Command "& {& '%Commander_Path%\_T e s T\Test datei.ps1' Abc XXX 678}"
Parameters:

Test datei.ps1:
"---"
$Args
"---"
$Args[0]
"---"
$Args[1]
"---"
"Alle: $Args"
"1: $($Args[0])"
"2: $($Args[1])"
"3: $($Args[2])"
"---"


Ergebnis:
---
Abc
XXX
678
---
Abc
---
XXX
---
Alle: Abc XXX 678
1: Abc
2: XXX
3: 678
---




Quoting
Befehle und Pfade mit Leerzeichen müssen in Quotes gesetzt werden: "...".
Auf dem Weg zur Ausführung entfernen "die Interpreter" die jeweils äußeren Quotes.
Deshalb muss man im TC die Quotes verdreifachen: """....""".
Oder man verwendet einfache Anführungszeichen: '...', dann behandelt PowerShell
diese Zeichenketten aber anders als in "..." und löst $variablen nicht auf.

Der Interpreter trennt den kompletten Befehl an Leerzeichen in die unterschiedlichen Bestandteile:

Beispiel

C:\Program\Anwendung\A.exe C:\Temp\Datei.txt
ist einfach:
Program .: C:\Program\Anwendung\A.exe
Parameter: C:\Temp\Datei.txt


C:\Program Files\Anwendung\A.exe C:\Temp\Test Datei.txt
ist schon komplizierter:
Program .: C:\Program
Parameter: Files\Anwendung\A.exe
Parameter: C:\Temp\Test
Parameter: Datei.txt
Hier wird der Interpreter sich beschweren: "C:\Program " ist unbekannt.
Deshalb muss man hier Anführungszeichen setzen:
"C:\Program Files\Anwendung\A.exe" "C:\Temp\Test Datei.txt"
Program .: C:\Program Files\Anwendung\A.exe
Parameter: C:\Temp\Test Datei.txt

Anführungszeichen kann man auch immer setzen, auch wenn keine Leerzeichen
vorhanden sind, wie im ersten, einfachen Beispiel:
"C:\Program\Anwendung\A.exe" "C:\Temp\Datei.txt"

Machmal muss man auch den kompletten Befehl nochmal in Quotes setzen:
" "C:\Program\Anwendung\A.exe" "C:\Temp\Datei.txt" "

Und da zb TC als Interpreter die äußeren Quotes entfernt,
muss man expliziet sagen, dass man Quotes möchte:
""" "C:\Program\Anwendung\A.exe" "C:\Temp\Datei.txt" """

Es kommt immer auf das Programm / den Interpreter an, wie man was quoten muss...> experimentieren!


Interpreter
Kurz gesagt; "Programm" um einen Befehl oder ein Skript einzulesen, auszuwerten und zu verarbeiten.
Wenn der TC einen Benutzerbefehl (zb Button) auswertet, verwendet er ein Stück Programmcode als Interpreter.
Die CMD.exe und die Powershell.exe, sowie cScript.exe und wScript.exe bei VBScript sind ebenfalls Interpreter.
Jeder Interpreter interpretiert die Zeichenkette (Befehl, Parameter, Leerzeichen, Quotes, Sonderzeichen) anders
und man muss manchmal (oft) tricksen, um alle Interpreter zufrieden zustellen. (Siehe Abschnitt "Quoting")


Semicolon
Durch ein Semikolon ";" kann man einzelne Befehle trennen und nacheinander abarbeiten.
$A=20 ; $A++ ; $A #Ergebnis: 21


Piping
Durch "|"-Pipe Zeichen wird die Ausgabe des linken Befehls als Eingabe für den rechten Befehl angesehen.
1,2,3 | ForEach{ $_ * 2 } #Ergebnis: 2 4 6


Kommandozeilentrennung
Kommandozeilen dürfen nach einem Pipe- oder Semikolon Symbol umgebrochen werden.
Dies kann in einem Skript, oder in einem Forums-Post verwendet werden, um Einzeiler verständlicher aufzubereiten.

Falls die PoSh in der Konsole diese zwei ">>" Zeichen anzeigt, dann bedeutet das, dass der Befehl
noch nicht komplett eingegeben wurde,... irgendetwas fehlt noch, eventuell fehlt eine Klammer?
Schaue den Befehl noch mal komplett nach und ergänze das fehlende Teil, jetzt in der Zeile mit den beiden ">>".
Beende diese Eingabe mit einer leeren ">>" Zeile plus <ENTER>

Allgemein gilt:
Mit Strg+C kann man die aktuelle Zeile ohne Ausführung verlassen und in der nächsten Zeile noch mal frisch starten.



Schreibweise
Die Groß-/Kleinschreibung spielt keine Rolle.
Bei Befehlen, bei dehnen die Schreibweise wichtig sein kann (zB -Replace) gibt es gesonderte Parameter um dies zu berücksichtigen.
Leerzeichen zwischen Befehlen und Parametern werden raus gefiltert.


Leerzeichen
Zwischen den einzelnen Befehlen und Parametern (auch vor und nach dem Pipe-Zeichen und nach dem Semikolon)
werden ein (oder beliebig viele) Leerzeichen eingefügt.
Manchmal kann man aber auch das (die) Leerzeichen weg lassen, da der Interpreter dies unterscheiden kann.
Das macht man, um möglichst kurze Einzeiler zu schreiben (und um anzugeben), stört aber oft das Verständnis und manchmal auch den Interpreter.


TAB-Vervollständigung
Drücke die Tab-Taste um angefangene Befehle zu vervollständigen:
Get-P <TAB> >>>> Get-Process <TAB> >>> Get-PSDrive <TAB> >>> Get-PSProvider .... u.s.w.


Variable
Zeichenketten wie zB '$meinName' sind Variablen
Variablen sind quasi eine Art "Behälter" in welchen etwas aufgehoben wird. Mit dem $VariablenNAMEN kann darauf zugreifen.
$Beispiel = "dies hier wird in $Beispiel" gespeichert."
$Beispiel # gibt den Inhalt wieder



"Eingebaute" Standard-Variable / Automatic Variables
Siehe HELP about_Automatic_Variables

https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables
$$
$?
$^
$_ $PSItem
$ARGS
$CONSOLEFILENAME
$ERROR
$EVENT
$EVENTARGS
$EVENTSUBSCRIBER
$EXECUTIONCONTEXT
$FALSE
$FOREACH
$HOME
$HOST
$INPUT
$LASTEXITCODE
$MATCHES
$MYINVOCATION
$NESTEDPROMPTLEVEL
$NULL
$OFS
$PID
$PROFILE
$PSBOUNDPARAMETERS
$PSCMDLET
$PSCOMMANDPATH
$PSCULTURE
$PSDEBUGCONTEXT
$PSHOME
$PSITEM
$PSSCRIPTROOT
$PSSENDERINFO
$PSUICULTURE
$PSVERSIONTABLE
$PWD
$SENDER
$SHELLID
$STACKTRACE
$THIS
$TRUE

Keywords
Siehe HELP about_Language_Keywords

https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_language_keywords
Begin
Break
Catch
Class
Continue
Data
Do
DynamicParam
Else
Elseif
End
Enum
Exit
Filter
Finally
For
ForEach
From
Function
If
In
InlineScript
Hidden
Parallel
Param
Process
Return
Sequence
Static
Switch
Throw
Trap
Try
Until
Using
While
Workflow



Kommentare
Alles hinter einem '#'-Zeichen wird als Kommentar angesehen
# line comment
Get-Process # Liste alle Prozesse auf


Integrierte Hilfe
Get-Help
Get-Help Get-Help # Hilfe zur Hilfe
Get-Help * -detailed -full -examples -parameter
Get-Help get-
Help *Objekt*
Help about*

Function Get-HelpBrief{param($Name)(Get-Help $Name).Parameters.Parameter|Select Name,@{n='Help';e={-join $_.Description.Text}}}


$PSItem
Das "$_" Zeichen ist eine Variable mit dem Inhalt des aktuell bearbeiteten Elements (Objekt/Zeile/Datei/..)


{...}
Zusammenhängendes wird in {...} Klammern eingeschlossen.


ForEach-Objekt{...}
Mit dem ForEach-Objekt (Kurzform "ForEach", Alias "%", oder im TC verdoppelt: "%%") wird jedes "$_" einzeln abgearbeitet.
PS> Get-ChildItem | ForEach{ "Aktuelle Zeile ist: " + $_.Name }
-oder-
PS> Get-ChildItem | ForEach{ "Aktuelle Zeile ist: $_.Name" }
-oder-
PS> Get-ChildItem | %{ "Aktuelle Zeile ist: $_.Name" } # PowerShell "normal"
PS> Get-ChildItem | %%{ """Aktuelle Zeile ist: $_.Name""" } # "%" im TC verdoppelt und Quotes verdreifacht

-FALSCH, siehe oben Quoting:
PS> Get-ChildItem | ForEach{ 'Aktuelle Zeile ist: $_.Name' }

- - -

Innerhalb einer "ForEach{...}"-Schleife wird jedes Element der Eingabe einzeln abgearbeitet.
Hierzu wird die Variable "$_" bzw. "$PSItem" als Platzhalter für ein Element verwendet.
Um welche "Elemente" es sich jeweils handelt, kommt auf den vorherigen Befehl an.
Ein Element ist je nach Befehl zB eine Datei oder zB eine Zeile einer Textdatei.

Beispiele:
Get-ChildItem | ForEach{ $_ ist jeweils eine Datei aus dem Ordner }
Get-Content test.txt | ForEach{ $_ ist jeweils eine Zeile von test.txt }
1..5 | ForEach{ $_ ist jeweils eine Ziffer von 1 bis 5}
Get-Process | ForEach{ $_ ist jeweils ein Process}


$_ repräsentiert dabei jeweils ein Objekt (siehe unten bei "Objekt") und nicht nur die bloße Information der Textausgabe.


- - -

Das ForEach-Object erlaubt die Verwendung von einem, zwei oder drei Skriptblöcken


Normalfall:
GCI | ForEach{ Befehl(e) für jedes Object einmal ausgeführt, zB $count+=$_.Length }

Zwei Blöcke:
GCI | ForEach{ initial, nur ein mal ausgeführt, zB $count=0 }{ Befehl(e) }

Drei Blöcke:
GCI | ForEach{ initial }{ Befehl(e) } { Abschluss, nur einmal ausgeführt, zB "Ergebnis ist: $count" }

Der Anwender kann endscheiden, ob er mit einen, zwei oder drei Skriptblöcke sein Skript aufbaut.
Oder man verwendet diese Alternative, wie sie auch bei anderen Skriptsprachen verwendet werden würde:
$count=0; GCI | ForEach{ $count+=$_.Length };   "Ergebnis ist: $count"


Der ForEach Befehl
Neben dem ForEach-Object gibt es noch das ForEach Kommando:

Alle Verzeichnisse auflisten:
$Ordner = Get-ChildItem | Where{$_.mode -match "d"}
ForEach ($ITEM in $Ordner) { Write-Host $ITEM.fullname }



Where-Object (Kurzform: "?")
Get-ChildItem | Where{ $_.Name -like "*total*"}
alias | where { $_.definition -like "*item*" }


if( Bedingung ) { A } else { B }
1,2,3 | ForEach{ IF($_ -eq 2){'Ja'}else{'Nein'} }
Nein
Ja
Nein


while (Bedingung) { C }
1..6| ForEach{ $C=$_ ; ; $C }
1
2
3
4
5
6
1..6| ForEach{ $C=$_; While( $C -lt 4 ){$C++}; $C }
4
4
4
4
5
6




Array
Jeder Befehl, welcher mehr als ein Element ausgibt, wird automatisch in ein Array konvertiert.
Mittels "@("inhalt")" oder einem führendem Komma (,"inhalt") kann man die Erstellung eines Arrays (auch bei nur einem einzelnen Element) erzwingen.

Array erstellen:
$NeuesArray1 = @()
$NeuesArray2 = "Eins","Zwei","Drei"

$NeuesArray3a = "Sechs"
$NeuesArray3a -is [array] #False

$NeuesArray3b = ,"Sechs" # Führendes Komma!
$NeuesArray3b -is [array] #True

$NeuesArray3c = @("Sechs") # in "@()"
$NeuesArray3c -is [array] #True

$NeuesArray3.GetType()

$NeuesArray4 = "abc,def,ghi,4,5".split(",")

$NeuesArray5 = GCI
$NeuesArray6 = GC .\Text.txt


Array erstellen:
$farben = "Schwarz","Weiß","Gelb","Blau"
$farben -is [array] #True

Array befüllen:
$farben = $farben + "Orange"
$farben += "Grün"
$farben[2] = "Lila"

Array ausgeben:
$farben
$farben[0] # erstes Element ausgeben
$farben[1,4,7] # zweites, fünftes,.. Element
$farben[-1] # letztes Element ausgeben

Array überprüfen:
IF($farben[2 .. 6] -cContains "Blau"){"Ja"}else{"Nein"}
$farben[2 .. 6] -cLike "gel*"

Compare-Object -ReferenceObject ($a1) -DifferenceObject ($a2) -PassThru
$A1 =@((gc '.\Computernames-A.txt'))
$A2 =@((gc '.\Computernames-B.txt'))
compare $a1 $a2


Array sortieren:
$farben | Sort

Array löschen/Aufräumen:
$farben = $null
$farben = $farben | where {$_ -ne "Gelb"} # alles außer des "Gelb"en Eintrages




Associative Arrays (Hash Tables) (Dictionaries)
$h = @{} # create a empty hash table
$h = @{ Key1=Value1; Key2=Value2; Key3=Value3}
$h = @{ one=1; two="value"} # create hash table
[ordered]@{a=1;b=3;c=2} # ordered dictionary
$h.one = 5 # Set "one" to "5"
$h["two"] # returns "value"
$h.GetEnumerator | sort key # unwrap this object into it’s individual elements and sort by key
$h.GetEnumerator() | ForEach-Object { ... }
ForEach($item in $h.GetEnumerator()) {Echo $item ... }
$h.Add("three", "Tree")
$h.Set_Item("three", "Three")
$h.Remove("three")
$h.ContainsKey('two')
$h.ContainsValue('1')





Welche PS-Version habe ich?
Der aktuelle Host, zB die PoSh-Konsole selbst.
Get-Host (oder $Host)
Version : 2.0


Die installierte PoSh-Version selbst (meistens kein Unterschied zu $Host)
$PSVersionTable
CLRVersion 2.0.50727.5485
PSVersion 2.0
PSCompatibleVersions {1.0, 2.0}



Bestimmte Version im Skript als Voraussetzung setzen
Set-StrictMode -Version "2.0"

-oder-
#requires -version 3.0

-oder zB-

If ($PSVersionTable.PSVersion.Major -ge 4)
{
# Enter PS 4.0 code here
Write-Host("Your powershell version is 4.0")
}
Else
{
# Enter code here
Write-Error("You need at least Powershell 4.0 to run this program. Powershell is part of the Windows Management Framework
and can be downloaded here: http://www.microsoft.com/en-us/download/details.aspx?id=40855") -Category NotInstalled -ErrorId "PSVersion < 4.0"
}

-oder die PoSh in der gewünschten Version starten:
PowerShell -Version 2.0 -NoProfile -NoExit



Liste aller verfügbaren cmdlets (Verb-Noun syntax)
Get-Command
Get-Command Get-*
Get-Command -Verb set
Get-Command -Noun Loc*

"Standard"-cmdlets zum Kennenlernen
(einfach mal eintippen)
Get-ChildItem (Alias: gci oder DIR oder LS)
Get-Process (oder gps)
Get-Service (gsv)
Get-Date
Get-History (h)
Get-Host

Mit 'help get-xxx -Full' bekommt man die Hilfe, Parameter und Beispiele angezeigt.

Die Parameter kann man auch abkürzen, solange sie noch vom Interpreter eindeutig erkannt werden können.
Statt
'Get-ChildItem -Recurse -Filter *.txt'
kann man auch
'Get-ChildItem -r -fi *.txt'
verwenden (aber nicht '-f', probiert's mal aus und lest die Meldung)

Mit 'get-xxx | Get-Member' bekommt man die verfügbaren Eigenschaften angezeigt.



Liste aller Aliase
Get-Alias -Name *dir* # '-Name' oder '-n' prüft auf das Alias-Kürzel.
Get-Alias -Definition *childItem* # '-Definition' oder '-def' prüft auf den Befehl

Auch "Get-Alias" hat einen Alias, nämlich "alias"


Kleines Beispiel nebenbei; Alias-Liste erstellen und anzeigen:
Get-Alias | select Name, ResolvedCommand, @{ Name="Description"; Exp={ Get-Help $_ | Select -ExpandProperty Synopsis }} | sort ResolvedCommand | Format-Table -Auto



Objekt
Alles ist ein Object, jede Datei, jede Zahl, jede Textzeile.
Jedes Object hat Eigenschaften wie zB Länge, Größe, Farbe, Alter, Anzahl Sitzplätze,...
Jedes Object hat Methoden/Funktionen wie zB ToUpper(), Split(), Beschleunigung(), Blinken(),...
Welche Eigenschaften und Methoden vorhanden sind, kommt auf die Implementieren des Objects an.
Mittels "Get-Member" kann man sich diese anzeigen lassen, siehe unten bei "Liste aller Member"


Liste aller Member (Eigenschaften und Functionen)
Alles in PoSh ist ein Objekt, und Objekte haben Eigenschaften und Funktionen.
Um diese aufzulisten, verwende "Get-Member" (Alias: gm):
Get-Process | Get-Member
Get-Process | Get-Member -force -MemberType noteproperty | select name
"Hello" | gm
42 | gm
Durch "Get-Member" kannst du erkennen, was du mit den Objekten alles standardmäßig machen kannst.
zB "Get-ChildItem | Get-Member" zeigt dir unter Anderem:
Exists
IsReadOnly
Attributes
CreationTime
LastAccessTime
LastWriteTime
DirectoryName
FullName
Name
BaseName
Extension
VersionInfo
Diese Eigenschaften und Methoden kannst du dann auf die einzelnen Elemente des "Get-ChildItem"-Befehls anwenden/abfragen/usw.



Reserved Words
Reserved Words - the following may not be used as identifiers (unless surrounded in quotes)
break, continue, do, else, elseif, for, foreach, function, filter, in, if, return, switch, until, where, while.




Zeilenumbruch EOL
`r`n


- - -

Weiterführende Infos (zufällig gefunden, wahllos aufgelistet, von mir nicht getestet)

http://www.powershellpraxis.de/index.php/grundlagen/die-drei-wichtigsten-cmdlets

https://www.msxfaq.de/code/powershell/index.htm

6.2.3 Die Windows PowerShell
http://openbook.rheinwerk-verlag.de/it_handbuch/06_002.html#dodtpc7716133-b2c0-44f1-bdd1-9cb344ab990b

Skripterstellung mit Windows PowerShell
https://technet.microsoft.com/de-de/library/bb978526.aspx

https://www.sepago.de/blog/2015/10/09/new-sepagotraining-grundlagenkurs-how-to-windows-powershell

Table of Basic PowerShell Commands / The Scripting Guys - June 11, 2015
https://blogs.technet.microsoft.com/heyscriptingguy/2015/06/11/table-of-basic-powershell-commands/


https://devlabor.com/powershell-schnelleinstieg-und-nuetzliche-snippets/


OpenBook von Martin Lehmann, eine einzige. lange HTML-Seite
http://www.martinlehmann.de/PowerShell123.htm



Spickzettel / Cheat Sheet
https://entwickler.de/wp-content/uploads/2017/02/Powershell_Spickzettel_entwickler.de_.pdf
http://ramblingcookiemonster.github.io/images/Cheat-Sheets/powershell-basic-cheat-sheet2.pdf
http://smenne.de/Referenzen/ReferenzPowerShell.pdf


- - -

Beispiel aus dem Forum:

viewtopic.php?t=41218
CopyFileToMany
? 1..13 | ForEach{COPY '%P%N' $("""%P%O_{0:D4}.%E""" -f $_)}

? -Command &{ 1..3 | ForEach{COPY """%P%N""" ("""%P%O_{0:D4}.%E""" -f $_)}}
? -Command &{ 5..6 | ForEach{COPY '%P%N' ("""%P%O_{0:D4}.%E""" -f $_)}}




http://ghisler.ch/board/viewtopic.php?t=39475&highlight=powershell
Dateien in allen Unterordnern durchnummerieren, jeweils den Zähler zurücksetzen
Get-ChildItem |
Where-Object {$_.PSISContainer -eq $true}|
Foreach-Object {$ParentFolderName=$_.Name; cd $_.FullName; $count=0; Get-ChildItem} |
Foreach-Object {$count++; Rename-Item -Path $_.FullName -NewName ( ("$ParentFolderName - " + $_.BaseName) + ("_{0:D4}" -f $count)+ ($_.Extension))}; cd..
 


http://ghisler.ch/board/viewtopic.php?t=39661&highlight=powershell
ein jemand möchte gerne alle Unterverzeichnisse eines Ordners so umbenennen,
wie die Datei mit dem längsten Namen innerhalb des jeweiligen Unterverzeichnisses.
$Len=0;ls|%{$CurLen=$_.Name.length;IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName; $Dir=$_.DirectoryName}};cd..;ren -path $Dir -NewName $NewName



http://ghisler.ch/board/viewtopic.php?t=39137&highlight=powershell
ich habe einige Dateien mit einem Datums-/Zeitstempel im Namen.
Auf dieses Datum würde ich gern das Erstellungsdatum der Datei setzen
gci|?{$_.Name -match """\d{4}-\d{2}-\d{2}"""}|%%{$d=$matches[0]+""" 12:33""";$_.LastWriteTime=$d;$_.CreationTime=$d}



http://ghisler.ch/board/viewtopic.php?t=39126&highlight=powershell
Merge TXT files to _outfile.txt
-command $out=""""""; foreach($file in dir *.txt){$out += """Content of $file`r`n`r`n""" + [System.IO.File]::ReadAllText($file, [System.Text.Encoding]::Default ) + """`r`n`r`n##### EOF #####`r`n`r`n"""}; $out | out-file _outfile.txt




http://ghisler.ch/board/viewtopic.php?t=40488&highlight=powershell
In mehreren Verzeichnissen habe ich alle möglichen Dateien gemischt. Bilder, PDFs, Texte, etc.
Ich benötige ein Plugin, welches mit z.B. über die Mehrfachumbenennfunktion die Anzahl der Textdateien zählt, und ausgibt.
PS C:\TEMP> ls -recurse | where{ $_.Extension -eq ".txt" } | group Extension -NoElement
PS C:\TEMP> ls -recurse | group Extension -NoElement
PS C:\TEMP> ls -recurse | group Extension -NoElement | sort name -desc
PS C:\TEMP> ls -recurse | group Extension -NoElement | sort count



http://ghisler.ch/board/viewtopic.php?t=40409&highlight=powershell
How to change file names (renumbering)
ls | ?{$_.Name -notlike "*@*"} | %{$a=$_.Name.split("#"); $n=([int]$a[0] +1); $nn=([convert]::ToString($n)+"#"+$a[1]);ren -path $_.FullName -newname $nn;}



http://ghisler.ch/board/viewtopic.php?t=40563&highlight=powershell
I want create "File_ID.txt" empty file and open it with only a button.
If I use Shift+F4 I have to write the filename but I'am looking for a quicker mode.
If not exist File_ID.txt, create it. After that decision, open the file in notepad.exe:
$file=$pwd.path+"\File_ID.txt"; if(!$file.Exist){new-item -path $file -type "file"}; notepad $file;
---
Create on every execution a file with a new ID:
File_ID1.txt
File_ID2.txt
File_ID3.txt
$id=1; $file=$pwd.path+"""\File_ID$id.txt"""; while(test-path $file){$id++;$file=$pwd.path+"""\File_ID$id.txt"""}new-item -path $file -type """file"""; notepad $file
---
Or formate bx pad to length of three digits:
File_ID001.txt
File_ID002.txt
File_ID003.txt
File_ID004.txt
$id=1; $file=$pwd.path+"""\File_ID{0:D3}.txt""" -f $id; while(test-path $file){$id++;$file=$pwd.path+"""\File_ID{0:D3}.txt""" -f $id}new-item -path $file -type """file"""; notepad $file



http://ghisler.ch/board/viewtopic.php?t=41052&highlight=powershell
remove trailing slash from CopyNameToClipboard
TYPE "%L" | Foreach{$_ -Replace """\\$"""}|clip



http://ghisler.ch/board/viewtopic.php?t=41902
Batch CRC-tool
I want to calculate CRC of different directory. Is there a way to use crc tools in a sequential mode?



http://ghisler.ch/board/viewtopic.php?t=41145&highlight=powershell
... is there a simple way within TC where you can make a copy of a file in the same directory/folder?
For one OR all selected files (with or without extension) or folders:
TYPE %L|%%{$C=2;$O=$_;if(Test-Path $O){if((dir $O).PsIsContainer -or ($O -notmatch """\."""))
{$O=$O -replace """\\$""";$N="""$O($C)""";while(Test-Path $N){$C++;$N="""$O($C)"""}}else
{$O -match """(.+)\.(.+)""";$B=$matches[1];$E=$matches[2];$N="""$B($C)$E""";while(Test-Path $N){$C++;$N="""$B($C)$E"""}}};copy """$O""" """$N"""}



http://ghisler.ch/board/viewtopic.php?t=41078&highlight=powershell
Sometimes I need to copy a file, but update the creation date/time to now for new file
Copy selected file to target panel and set date and time to Now()
Copy """%P%N""" """%T%N"""; (Dir """%T%N""").LastWriteTime = Get-Date




http://ghisler.ch/board/viewtopic.php?p=291870#291870
kann ich irgendwo einstellen, dass cm_CopyFullNamesToClip statt \ als Pfadtrenner / verwendet?
TYPE """%L""" | Foreach{$_ -Replace """\\\\""" . """/"""}|clip
-oder besser-
TYPE '%L' | Foreach{$_ -Replace [regex]::escape('\'), '/'} | clip



viewtopic.php?t=48095
Erstelle 20 Zeilen mit gleichem Text und aufsteigenden Nummern
1..20|ForEach{$a=9;$b=279}{$a++;$b++; "cm_SrcCustomView$a=$b"}
cm_SrcCustomView10=280
cm_SrcCustomView11=281
...
cm_SrcCustomView19=289
cm_SrcCustomView20=290
...
cm_SrcCustomView28=298
cm_SrcCustomView29=299



viewtopic.php?t=47504
is it possible to change the date/time of files relative to their existing date/time?
E.g., the files have a date of 2016-12-12 and I want to change the filedates back a year 2015-12-12
GCI | ForEach{ $_.LastWriteTime = ($_.LastWriteTime).AddYears(-1) }
# // some alternatives:
# CreationTime
# LastWriteTime
# LastAccessTime
# AddDays
# AddHours
# AddMilliseconds
# AddMinutes
# AddMonths
# AddSeconds
# AddTicks
# AddYears
# Usage:
# AddYears(2) # add plus two years
# AddYears(-4) # extract minus four years



viewtopic.php?t=44027
Ich hätte gerne die Verzeichnisse mit Staffel 2 bis 4 (oder auch mehr) immer in das Staffel 1 Verzeichnis verschoben.
Dir|Where{$_.PSIsContainer}|ForEach{$SN=$_.Name.substring($_.Name.Length -1,1);$Fld=$_.Name.Substring(0,$_.Name.Length-1)+'1';If($SN -ne 1){MOVE $_ $Fld}}




viewtopic.php?t=44026
change timestamp by file's name,such as IMG_20151205_234758.jpg will change timestamp to 2015.12.05 23:47:58.
Dir | ForEach{$TS=$_.BaseName -replace '....(....)(..)(..)_(..)(..)(..)','$1-$2-$3 $4:$5:$6';$_.LastWriteTime=$TS;$_.CreationTime=$TS}



viewtopic.php?t=43864
appends filenames at the bottom of all txt file in the directory.
Command: powershell.exe
Parameters: -NoProfile -ExecutionPolicy remotesigned -Command "&{&'C:\PathTo\AddFileName.ps1' -FileList '%L'}"
AddFileName.ps1: siehe Link

Append FILENAME to File content:
Command: PowerShell -NoProfile
Parameters: TYPE '%F' | %%{IF( @(gc $_ )[-1] -NotMatch """^\s*$"""){Add-Content $_ """`r`n"""};Add-Content $_ $_ }



viewtopic.php?t=43124
Ich möchte gerne bei vielen Verzeichnissen eine Quersumme pro Verzeichnis erstellen (checksum crc md5 sha)
Kommando: powershell.exe
Parameter: -NoExit -ExecutionPolicy remotesigned -Command "&{&'C:\PfadZu\CreateChecksum.ps1' -listFile '%L'}"
"CreateChecksum.ps1" siehe Link




viewtopic.php?t=42092
How to make duplicates with different names from a single file
( Get-Content .\FileList.txt ) | ForEach{ Copy-Item -Path .\Origin.ext -Destination $_ }
In short:
(gc .\FileList.txt)|%{copy .\Origin.ext $_}



viewtopic.php?t=41790
Textdatei nach mehreren Begriffen durchsuchen
Hier mal nen quick&dirty PowerShell Skript: siehe Link



viewtopic.php?t=41301
ist es möglich Dateien zu suchen und automatisch durch eine neue zu ersetzen?
$new="C:\Work\Release1.1\MyApp.exe"; dir E:\Test\Release\Last -Recurse -Filter "MyApp.exe"|ForEach{Copy $new $_.FullName -Force -WhatIf}



viewtopic.php?t=39661
Verzeichnisnamen nach längster Datei innerhalb umbenennen?
$Len=0;ls|%{$CurLen=$_.Name.length;IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName; $Dir=$_.DirectoryName}};cd..;ren -path $Dir -NewName $NewName

LS = Get-ChildItem
% = ForEach-Object
ren = Rename-Item

Als Nächstes könnte man um dieses Skript herum eine ForEach Schleife bauen und auf den Hauptordner loslassen...
Einfach ein weiteres "dir | ForEach{ ... }" drumherum setzen.

Oder, je nach Anforderung ein "dir | Where{$_.PSisContainer -eq $true} |ForEach{ ... }" um wirklich nur Ordner zu bearbeiten.

Etwa so:
Get-ChildItem |
Where-Object{$_.psiscontainer -eq $true}|
ForEach-Object{cd $_.Name; $Len=0; Get-ChildItem|
ForEach-Object{$CurLen=$_.Name.length; IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName; $Dir=$_.DirectoryName}}; cd..; Rename-Item -Path $Dir -NewName $NewName}

Oder in Kurzform mit Aliase:
ls | ?{$_.psiscontainer -eq $true}| %{cd $_.Name; $Len=0;ls|%{$CurLen=$_.Name.length;IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName;$Dir=$_.DirectoryName}}; cd..; ren -Path $Dir -NewName $NewName}

Aber Achtung, das Skript wurde nur an Beispieldateien getestet und hat keine Fehlerbehandlung.




viewtopic.php?p=330390#330390
PowerShell: Kopiere Datei nach Target und hänge einen Timestamp an
Get-Content '%L'|Foreach{$obj=(GI $_);$NewName=($obj.BaseName+"""_{0:yyyy-MM-dd_HHmm}""" -f $obj.LastwriteTime + $obj.Extension);COPY $obj """%T$NewName"""}

-oder-
+"""_( backup stand {0:dd.MM.yyyy_HHmmss} )"""




viewtopic.php?p=279078#279078
Dateien umbenennen und Zähler für jeden Ordner wieder bei Null anfangen

Get-ChildItem | Where-Object {$_.PSISContainer -eq $true}|
Foreach-Object {cd $_.FullName; $count=0; Get-ChildItem} |
Foreach-Object {$count++; Rename-Item -Path $_.FullName -NewName ($_.BaseName + "_{0:D4}" -f $count + $_.Extension)}; cd..



- - -

Just found this at Richard Siddaway's Blog:
https://blogs.msmvps.com/richardsiddaway/2018/06/29/powershell-versions-3/


PowerShell versions
Published June 29, 2018

PowerShell has gone through a number of versions since it was first released in November 2006.
These are the major features of the PowerShell versions:

PowerShell v1 – initial release with 137 cmdlets. (released with Windows Vista / Server 2008 – not Server Core).
Only way to work remotely was Get-WmiObject. no longer available.
PowerShell v2 (Windows 7 / Server 2008 R2) – introduced PowerShell remoting, PowerShell jobs and extended WMI cmdlets. Deprecated.
PowerShell v3 (Windows 8 / Server 2012) – Workflows, CIM cmdlets
PowerShell v4 (Windows 8.1 / server 2012 r2) – DSC
PowerShell v5 (Windows 10) – PowerShell classes
PowerShell v5.1 (Windows 10 Update / Server 2016) – mainly bug fixes for v5
PowerShell v6.0 (open source) – SSH remoting, installs for Linux and mac
PowerShell v6.1 (in development) – mainly fixes and updates to v6.0


Documentation has become weaker over time and is currently available from
- https://docs.microsoft.com/en-gb/powershell/scripting/powershell-scripting?view=powershell-6

Which version should you use?
If you’re on Windows use the version installed OR download and install the latest WMF package for your version of Windows.
PowerShell v6 is useful for non-domain remoting or remoting to Linux servers.

If you’re on Linux or mac the your only choice in v6.x


Thanks Richard !

- - -



 
Last edited by Stefan2 on 2017-07-21, 13:25 UTC, edited 33 times in total.
Post Reply