Hybrydowy skrypt CMD-PowerShell
+ 16.10.2024
(Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
- albo skrypt CMD).
Gdy chcemy uruchamiać skrypty PowerShell *.ps1
na swoim komputerze, to jednorazowo trzeba wpisać w oknie Powershell (Adminstrator):
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Podobno ma to być jakieś zabezpieczenie. Chyba nie jest, skoro można je obejść na 15 sposobów.
Generalnie można wklejać treść skryptu do konsoli Powershell bez powyższego zezwolenia.
Można też wykonać polecenie Powershell w jedno-wierszowym skrypcie CMD, np. pliku c.cmd
:
Powershell -NoExit -c "$c=Get-Culture; $c.DateTimeFormat"
-NoExit
- gdy nie chcemy abo po wykonaniu c.cmd
okno się zamykało;
po -c
wewnątrz polecenia "..."
można używać napisów '...'
.
2024-10-16: W Windows 11 jakoś znika ścieżka do PowerShell.exe
w zmiennej środowiskowej PATH
.
Czyli prawdopodobnie trzeba ją dodać: c:\Windows\System32\WindowsPowerShell\v1.0\
A na pewno trzeba dodać, gdy pojawia się komunikat:
‘powershell’ is not recognized as an internal or external command, operable program or batch file.
Można także skorzystać z hybrydowego pliku CMD-Powershell, tj. pliku *.CMD
, który nie wymaga odblokowania uruchamiania skryptów *.ps1
- po prostu zadziała u każdego. Jest to skrypt PowerShell z dodatkowym wierszem poleceń CMD na początku, np.:
@set pwsh=c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
@chcp 65001>nul&more +2 "%~f0"|%pwsh% -&pause&goto:eof
<#
Tu jest komentarz powershell
Pamiętaj - `more` - nie więcej niż 65536 wierszy.
#>
'Wygląda na to, że po `#>` lub `"@` czy `}` powinien być pusty wiersz lub #...'
${ąćę} = "ĄĆŁĘŃÓŚŹŻ ąćłęńóśźż €"
"TEST-polskie literki (kodowanie pliku: utf-8 bez BOM) - ${ąćę}"
@"
===
Uwaga - Ten plik "cmd" należy zapisać w kodowaniu UTF-8.
"@
"==="
Pierwszy wiersz to skrót do pełnej ścieżki PowerShell.exe
.
Drugi wiersz pliku cmd
przekazuje zawartość pliku - tego który jest właśnie uruchomiony ("%~f0"
), jako strumień poleceń PowerShell (|powershell -
) z pominięciem pierwszego i drugiego wiersza (more +2
). Na koniec są wywoływane jeszcze polecenia pause
i goto:eof
. Początkowe chcp 65001
włącza kodowanie UTF-8 i w takim właśnie kodowaniu należy zapisać plik *.cmd
.
Wygląda na to, że w Win11 może to być też kodowanie UTF-8 z BOM.
Taki skrypt np. o nazwie 1.cmd
można uruchomić wprost z eksploratora plików:
- W wybranym folderze utwórz plik
1.cmd
o treści jak powyżej (np. użyj notatnika, zapisz jako, kodowanieUTF-8
). - W pasku adresu, gdzie zwykle znajduje się zapis ścieżki do foldera wpisz
1.cmd
i naciśnij[Enter]
. Plik1.cmd
można umieścić w folderze dodanym do ścieżki PATH i wtedy powyższa metoda zadziała w dowolnym folderze. Zamiast tego wpisywania1.cmd
można też 2x kliknąć na tym pliku, choć czasem trzeba przejść jednorazowo przez kilka ostrzeżeń. - Po wykonaniu skryptu naciśnij
[Enter]
albo zamknij okno wyników.
W Win11 przed 2024r w domyślnym terminalu czasem nie działały niektóre funkcje w pliku hybrydowym “*.cmd”, np. przeskakiwane bywa okienko uwierzytelniania (nie wyskakiwało). Można wtedy użyć “starszej” wersji terminala “conhost.exe”, czyli wtedy w pasku adresu wpisać
conhost 1.cmd
Polecenie zapisane w skrócie *.LNK
Polecenie 1-wierszowe, które mogło by być w pliku *.CMD
można też zapisywać w ramach skrótu *.LNK
. Musi to być 1 wiersz ograniczony do 260 znaków.
Przykład:
powershell.exe -NoExit -c "polecenie1 -ErrorAction SilentlyContinue;...;'Zrobione.'"
Takie polecenie może mieć maksymalnie 260-43 znaków (-43, bo i tak automatycznie dopisane będzie na początku
C:\Windows\system32\WindowsPowerShell\v1.0\
). Na zewnątrz ciągu poleceń oddzielonych ;
musi być "
, więc w środku warto używać '
dla łańcuchów.
Tu może się przydać używanie krótszych poleceń PowerShell - lista: get-alias
Informacja sprzed 2024r - mam nadzieję, że już mało potrzebna:
Można także skorzystać z hybrydowego pliku CMD-Powershell, tj. pliku *.CMD
, który nie wymaga odblokowania uruchamiania skryptów *.ps1
- po prostu zadziała u każdego. Jest to skrypt PowerShell z dodatkowym wierszem poleceń CMD na początku, np.:
@chcp 1250>nul&more +1 "%~f0"|powershell -&pause&goto:eof
<#
Tu jest komentarz powershell
Pamiętaj - `more` - nie więcej niż 65536 wierszy.
#>
'Wygląda na to, że po `#>` lub `"@` czy `}` powinien być pusty wiersz lub #...'
${ąćę} = "ĄĆŁĘŃÓŚŹŻ ąćłęńóśźż €"
"TEST-polskie literki (kodowanie pliku: utf-8 bez BOM) - ${ąćę}"
@"
===
Uwaga - Ten plik "cmd" należy zapisać w kodowaniu ANSI (cp1250, Central European (Windows)).
"@
"==="
Pierwszy wiersz pliku cmd
przekazuje zawartość pliku - tego który jest właśnie uruchomiony ("%~f0"
), jako strumień poleceń PowerShell (|powershell -
) z pominięciem pierwszego wiersza (more +1
). Na koniec są wywoływane jeszcze polecenia pause
i goto:eof
. Początkowe chcp 1250
włącza kodowanie ANSI.
W Win11 w domyślnym terminalu czasem nie działały niektóre funkcje w pliku hybrydowym “*.cmd”, np. przeskakiwane bywa okienko uwierzytelniania (nie wyskakuje). Można wtedy użyć “starszej” wersji terminala “conhost.exe”, czyli wtedy w pasku adresu należy wpisać:
conhost 1.cmd
Kodowanie “utf-8”, czcionka raczej inna niż “Consolas”
Obecnie Notatnik Windows przyjmuje domyślnie kodowanie tekstu “utf-8” - i bardzo dobrze.
Dla takiego kodowania właściwe jest przełączenie strony kodowej skryptu na utf-8
tj. chcp 65001
:
@chcp 65001>nul&more +1 "%~f0"|powershell -&pause&goto:eof
<#
Tu jest komentarz powershell
Pamiętaj - `more` - nie więcej niż 65536 wierszy.
#>
'Wygląda na to, że po `#>` lub `"@` czy `}` powinien być pusty wiersz lub #...'
${ąćę} = "ĄĆŁĘŃÓŚŹŻ ąćłęńóśźż €"
"TEST-polskie literki (kodowanie pliku: utf-8 bez BOM) - ${ąćę}"
@"
===
Uwaga - w nowej wersji konsoli Win10 - czcionka `"Consolas`" jakoś przełącza się
na mikroczcionkę rastrową po wywołaniu Powershell przy chcp 65001 (=utf-8).
Ale np. `"Source Code Pro Medium`" działa dobrze.
Wystarczy jednorazowo zmienić na taką czcionkę "Właściwości" tego okna konsoli
(lewy, górny róg) zanim się go zamknie. Taka zmiana jest pamiętana w przyszłości.
"@
"==="
Pojawiają się drobne problemy z czcionką konsoli, które można zlikwidować zmieniając czcionkę np. na “Source Code Pro Medium” jak opisano powyżej.
Można też włączyć domyślne kodowanie UTF-8 dla wszyskich plików bez początkowego BOM - które dotąd były traktowane jako kodowanew ANSI lub OEM: https://stackoverflow.com/questions/57131654/using-utf-8-encoding-chcp-65001-in-command-prompt-windows-powershell-window (nie testowałem).
Nowa aplikacja terminala Microsoft Windows Terminal obsługuje domyślnie UTF-8. W Windows 10 trzeba ją zainstalować.
W Win 11 ten terminal jest domyślnie instalowany i domyślnie uruchamia się powershell, czcionka “Cascadia Mono”. A jednak domyślnie ma ustawione archaiczne kodowanie OEM (chcp -> 852). Można zmienić konfigurację startową powershell wpisując
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
Nazwa pliku konfiguracji jest w zmiennej $PROFILE
, która ma typowo wartość: <moje dokumenty>\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
.
Podobno wersja PowerShell 7 nie ma tej wady z podmianą czcionki.