Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Krátký popis
Popisuje, jak PowerShell analyzuje příkazy.
Dlouhý popis
Když zadáte příkaz na příkazovém řádku, PowerShell rozdělí text příkazu do řady segmentů, které se nazývají tokeny a pak určí, jak interpretovat jednotlivé tokeny.
Pokud například zadáte:
Write-Host book
PowerShell rozdělí příkaz na dva tokeny, Write-Host a booka interpretuje každý token nezávisle pomocí jednoho ze dvou hlavních režimů analýzy: režim výrazu a režim argumentů.
Poznámka:
Když PowerShell analyzuje vstup příkazu, pokusí se přeložit názvy příkazů na rutiny nebo nativní spustitelné soubory. Pokud název příkazu nemá přesnou shodu, PowerShell připojí Get- k příkazu jako výchozí sloveso. PowerShell například analyzuje Service jako Get-Service. Tuto funkci nedoporučujeme používat z následujících důvodů:
- Je neefektivní. To způsobí, že PowerShell bude prohledávat vícekrát.
- Externí programy se stejným názvem mají přednost, takže nemusíte spustit zamýšlený cmdlet.
-
Get-HelpaGet-Commandnerozpoznávají názvy bez sloves. - Název příkazu může být vyhrazené slovo nebo klíčové slovo jazyka.
Processje obojí a nedá se přeložit naGet-Process.
Režim výrazu
Režim výrazů je určený ke kombinování výrazů, které jsou vyžadovány pro manipulaci s hodnotami ve skriptovacím jazyce. Výrazy představují reprezentaci hodnot v syntaxi PowerShellu a můžou být jednoduché nebo složené, například:
Literální výrazy představují přímé vyjádření jejich hodnot:
'hello'
32
Výrazy proměnných mají hodnotu proměnné, na kterou odkazují:
$x
$script:path
Operátory kombinují další výrazy pro vyhodnocení:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- řetězcové literály znaků musí být obsaženy v uvozovkách.
- čísla jsou považovány za číselné hodnoty, nikoli jako řadu znaků (pokud nejsou uchycené).
-
Operátory, včetně unárních operátorů, jako jsou
-a-nota binární operátory, jako jsou+a-gt, jsou interpretovány jako operátory a aplikují jejich příslušné operace na argumenty (operandy). -
Atributové a konverzní výrazy se analyzují jako výrazy a aplikují se na podřízené výrazy. Například:
[int] '7'. - odkazy na proměnné se vyhodnocují na jejich hodnoty, ale použití "splattingu" je zakázáno a způsobuje chybu analyzátoru.
- Cokoli jiného se považuje za příkaz, který se má vyvolat.
Režim argumentu
Při analýze powershell nejprve interpretuje vstup jako výraz. Při vyvolání příkazu ale probíhá analýza v režimu argumentu. Pokud máte argumenty, které obsahují mezery, například cesty, musíte tyto hodnoty argumentů uzavřít do uvozovek.
Režim argumentů je určený pro analýzu argumentů a parametrů pro příkazy v prostředí. Veškerý vstup se považuje za rozbalitelný řetězec, pokud nepoužívá jednu z následujících syntaxí:
Znak dolaru (
$) následovaný názvem proměnné znamená odkaz na proměnnou, jinak je považován za součást rozšiřitelného řetězce. Odkaz na proměnnou může zahrnovat přístup ke členům nebo indexování.- Další znaky za jednoduchými odkazy na proměnné, například
$HOME, jsou považovány za součást stejného argumentu. Uzavřete název proměnné do složených závorek ({}) a oddělte ho od následných znaků. Například:${HOME}. - Pokud odkaz na proměnnou obsahuje přístup člena, první z dalších znaků se považuje za začátek nového argumentu. Například
$HOME.Length-moremá za výsledek dva argumenty: hodnotu$HOME.Lengtha řetězcový literál-more.
- Další znaky za jednoduchými odkazy na proměnné, například
Počáteční řetězce uvozovek (
'a")Složené závorky (
{}) začínají nový blok skriptu.Čárky (
,) představují seznamy předané jako pole, pokud není volán příkaz nativní aplikace, v takovém případě se interpretují jako součást rozbalitelného řetězce. Počáteční, po sobě jdoucí nebo koncové čárky se nepodporují.Závorky (
()) začínají novým výrazemOperátor dílčího výrazu (
$()) začíná vloženým výrazem.Počáteční znak (
@) začíná syntaxe výrazů, jako je splatting (@args), pole (@(1,2,3)) a literály tabulky hash (@{a=1;b=2}).(),$()a@()na začátku tokenu vytvoří nový kontext analýzy, který může obsahovat výrazy nebo vnořené příkazy.- Když následuje další znaky, první další znak se považuje za začátek nového samostatného argumentu.
- Když předchází necitovaný literál,
$()funguje jako rozbalitelný řetězec,()začne nový argument, který je výrazem, a@()je chápáno jako literál@, přičemž()začíná nový argument, který je výrazem.
Všechno ostatní je považováno za rozbalitelný řetězec, s výjimkou metacharacterů, které stále potřebují utéct. Viz Zpracování speciálních znaků.
- Metacharaktery v režimu argumentu (znaky se speciálním syntaktickým významem) jsou:
<space> ' " ` , ; ( ) { } | & < > @ #. Z těchto jsou< > @ #speciální pouze na začátku tokenu.
- Metacharaktery v režimu argumentu (znaky se speciálním syntaktickým významem) jsou:
Token zastavení zpracovávání (
--%) změní interpretaci všech zbývajících argumentů. Další informace najdete níže v části týkající se tokenu pro zastavení zpracování.
Příklady
Následující tabulka obsahuje několik příkladů tokenů zpracovaných v režimu výrazů a v režimu argumentů a vyhodnocení těchto tokenů. V těchto příkladech je hodnota proměnné $a4.
| Příklad | Režim | Výsledek |
|---|---|---|
2 |
Výraz | 2 (celé číslo) |
`2 |
Výraz | "2" (příkaz) |
Write-Output 2 |
Výraz | 2 (celé číslo) |
2+2 |
Výraz | 4 (celé číslo) |
Write-Output 2+2 |
Důvod | "2+2" (řetězec) |
Write-Output(2+2) |
Výraz | 4 (celé číslo) |
$a |
Výraz | 4 (celé číslo) |
Write-Output $a |
Výraz | 4 (celé číslo) |
$a+2 |
Výraz | 6 (celé číslo) |
Write-Output $a+2 |
Důvod | "4+2" (řetězec) |
$- |
Důvod | "$-" (příkaz) |
Write-Output $- |
Důvod | "$-" (řetězec) |
a$a |
Výraz | "a$a" (příkaz) |
Write-Output a$a |
Důvod | "a4" (řetězec) |
a'$a' |
Výraz | "a$a" (příkaz) |
Write-Output a'$a' |
Důvod | a$a (řetězec) |
a"$a" |
Výraz | "a$a" (příkaz) |
Write-Output a"$a" |
Důvod | "a4" (řetězec) |
a$(2) |
Výraz | "a$(2)" (příkaz) |
Write-Output a$(2) |
Důvod | "a2" (řetězec) |
Každý token lze interpretovat jako určitý druh typu objektu, například boolean nebo String. PowerShell se pokusí určit typ objektu z výrazu. Typ objektu závisí na typu parametru, který příkaz očekává, a na tom, jestli PowerShell ví, jak převést argument na správný typ. Následující tabulka uvádí několik příkladů typů přiřazených hodnotám, které vracejí výrazy.
| Příklad | Režim | Výsledek |
|---|---|---|
Write-Output !1 |
argument | "!1" (řetězec) |
Write-Output (!1) |
výraz | Nepravda (logická hodnota) |
Write-Output (2) |
výraz | 2 (celé číslo) |
Set-Variable AB A,B |
argument | "A", "B" (pole) |
CMD /CECHO A,B |
argument | "A,B" (řetězec) |
CMD /CECHO $AB |
výraz | A B (matice) |
CMD /CECHO :$AB |
argument | ':A B' (řetězec) |
Zpracování speciálních znaků
Zpětný apostrof (`) lze použít k úniku libovolného speciálního znaku ve výrazu. To je nejužitečnější pro odstranění metacharakterů v režimu argumentů, které chcete použít jako literální znaky, nikoli jako metacharakter. Pokud chcete například použít znak dolaru ($) jako literál v rozbalitelném řetězci:
"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.
Pokračování řádku
Znak backtick lze také použít na konci řádku a pokračovat s textem na dalším řádku. To zlepšuje čitelnost příkazu, který přijímá několik parametrů s dlouhými názvy a hodnotami argumentů. Například:
New-AzVm `
-ResourceGroupName "myResourceGroupVM" `
-Name "myVM" `
-Location "EastUS" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-Credential $cred
Měli byste se však vyhnout použití pokračování řádku.
- Znaky zpětné přehlásky mohou být obtížně viditelné a snadno zapomenutelné.
- Nadbytečné mezery po zpětném návazci přeruší pokračování řádku. Vzhledem k tomu, že je místo obtížně vidět, může být obtížné najít chybu.
PowerShell nabízí několik způsobů, jak zalomit řádky v přirozených bodech syntaxe.
- Za znaky svislé roury (
|) - Po binárních operátorech (
+,-,-eqatd.) - Za čárkou (
,) v poli - Po otevření znaků, jako jsou
[,{,(
Pro velkou sadu parametrů použijte místo toho splatting. Například:
$parameters = @{
ResourceGroupName = "myResourceGroupVM"
Name = "myVM"
Location = "EastUS"
VirtualNetworkName = "myVnet"
SubnetName = "mySubnet"
SecurityGroupName = "myNetworkSecurityGroup"
PublicIpAddressName = "myPublicIpAddress"
Credential = $cred
}
New-AzVm @parameters
Předávání argumentů nativním příkazům
Při spouštění nativních příkazů z PowerShellu se argumenty nejprve parsují pomocí PowerShellu. Analyzované argumenty se pak spojí do jednoho řetězce s každým parametrem odděleným mezerou.
Například následující příkaz volá program icacls.exe.
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Pokud chcete tento příkaz spustit v PowerShellu 2.0, musíte použít řídicí znaky, abyste zabránili chybné interpretaci závorek v PowerShellu.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Token zastavení analýzy
Počínaje PowerShellem 3.0 můžete pomocí tokenu zastavení analýzy (--%) zastavit interpretaci vstupu v PowerShellu jako příkazů nebo výrazů PowerShellu.
Poznámka:
Token stop-parsing je určen pouze pro použití nativních příkazů na platformách Windows.
Při volání nativního příkazu před argumenty programu umístěte token stop-parsing. Tato technika je mnohem jednodušší než použití řídicích znaků, aby se zabránilo nesprávné interpretaci.
Když narazí na token pro zastavení parsování, PowerShell považuje zbylé znaky na řádku za literál. Jedinou interpretací, kterou provádí, je nahradit hodnoty proměnných prostředí, které používají standardní notaci systému Windows, například %USERPROFILE%.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell odešle do icacls.exe programu následující příkazový řetězec:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Token pro zastavení parsování je efektivní jen do dalšího znaku nového řádku nebo roury. Znak pokračování řádku (`) nelze použít k rozšíření jeho efektu nebo ukončení jeho efektu pomocí oddělovače příkazů (;).
Kromě %variable% odkazů na proměnné prostředí nemůžete do příkazu vložit žádné další dynamické prvky. Uvedení znaku % jako %%, jak se to dá provést v dávkových souborech, není podporováno.
%<name>% tokeny se neustále rozšiřují. Pokud <name> neodkazuje na definovanou proměnnou prostředí, token se předává prostřednictvím as-is.
Přesměrování datového proudu (například >file.txt) nemůžete použít, protože se předávají doslovně jako argumenty cílovému příkazu.
V následujícím příkladu první krok spustí příkaz bez použití tokenu stop-parsing. PowerShell vyhodnotí řetězec v uvozovkách a předá hodnotu (bez uvozovek) do cmd.exe, což způsobí chybu.
PS> cmd /c echo "a|b"
'b' is not recognized as an internal or external command,
operable program or batch file.
PS> cmd /c --% echo "a|b"
"a|b"
Poznámka:
Při použití rutin PowerShellu není token stop-parsing potřeba. Může ale být užitečné předat argumenty funkci PowerShellu, která je navržená k volání nativního příkazu s těmito argumenty.
Předávání argumentů obsahujících znaky uvozovek
Některé nativní příkazy očekávají argumenty, které obsahují znaky uvozovek. PowerShell 7.3 změnil způsob analýzy příkazového řádku pro nativní příkazy.
Upozornění
Nové chování je zásadní změnou oproti chování prostředí Windows PowerShell 5.1. To může narušit skripty a automatizaci, které řeší různé problémy při vyvolání nativních aplikací. Pomocí tokenu stop-parsing (--%) nebo rutiny Start-Process se v případě potřeby vyhněte předávání nativního argumentu.
Toto chování řídí nová proměnná předvoleb $PSNativeCommandArgumentPassing. Tato proměnná umožňuje vybrat chování za běhu. Platné hodnoty jsou Legacy, Standarda Windows. Výchozí chování je specifické pro platformu. Na platformách Windows je výchozí nastavení Windows a na ne-Windows platformách je výchozí nastavení Standard.
Legacy je historické chování. Chování režimů Windows a Standard je stejné, kromě Windows, kde vyvolání následujících souborů automaticky používá předávání argumentů ve stylu Legacy.
cmd.execscript.exewscript.exe- končící na
.bat - končící na
.cmd - končící na
.js - končící na
.vbs - končící na
.wsf
Pokud je $PSNativeCommandArgumentPassing nastavená na Legacy nebo Standard, analyzátor tyto soubory nekontroluje.
Poznámka:
Následující příklady používají nástroj TestExe.exe. Můžete vytvořit TestExe ze zdrojového kódu. Viz TestExe ve zdrojovém úložišti PowerShellu.
Nové chování zpřístupněné touto změnou:
Literály nebo řetězce, které lze rozbalit, s vloženými uvozovkami jsou nyní zachovány:
PS> $a = 'a" "b' PS> TestExe -echoargs $a 'c" "d' e" "f Arg 0 is <a" "b> Arg 1 is <c" "d> Arg 2 is <e f>Prázdné řetězce jako argumenty jsou nyní zachovány.
PS> TestExe -echoargs '' a b '' Arg 0 is <> Arg 1 is <a> Arg 2 is <b> Arg 3 is <>
Cílem těchto příkladů je předat cestu k adresáři (s mezerami a uvozovkami) "C:\Program Files (x86)\Microsoft\" nativnímu příkazu, aby cestu přijala jako řetězec v uvozovkách.
V režimu Windows nebo Standard mají následující příklady očekávané výsledky:
TestExe -echoargs """${env:ProgramFiles(x86)}\Microsoft\"""
TestExe -echoargs '"C:\Program Files (x86)\Microsoft\"'
Pokud chcete dosáhnout stejných výsledků v režimu Legacy, je třeba uvozovky escapovat nebo použít token pro zastavení analýzy (--%):
TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\\"""""
TestExe -echoargs "\""C:\Program Files (x86)\Microsoft\\"""
TestExe -echoargs --% ""\""C:\Program Files (x86)\Microsoft\\"\"""
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""
Poznámka:
Zpětné lomítko (\) není v PowerShellu rozpoznáno jako escape znak. Jedná se o znak pro únik, který používá základní rozhraní API pro ProcessStartInfo.ArgumentList.
PowerShell 7.3 také přidal možnost trasovat vazbu parametrů pro nativní příkazy. Další informace naleznete v tématu Trace-Command.
Předávání argumentů příkazům PowerShellu
Počínaje PowerShellem 3.0 můžete pomocí koncového parametru tokenu (--) zastavit interpretaci vstupu v PowerShellu jako parametry PowerShellu. Toto je konvence zadaná ve specifikaci prostředí POSIX a nástrojů.
Token koncového parametru
Token konce parametrů (--) označuje, že všechny argumenty, za kterými následuje, mají být předány ve skutečné podobě, jako by se kolem nich umístily dvojité uvozovky. Například pomocí -- můžete zobrazit řetězec -InputObject bez použití uvozovek a bez interpretace jako parametru:
Write-Output -- -InputObject
-InputObject
Na rozdíl od tokenu stop-parsing (--%) je možné všechny hodnoty následující za tokenem -- interpretovat jako výrazy pomocí PowerShellu.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
Toto chování platí jenom pro příkazy PowerShellu. Pokud při volání externího příkazu použijete token --, předá se -- řetězec jako argument pro tento příkaz.
TestExe -echoargs -a -b -- -c
Výstup ukazuje, že -- je předán jako argument do TestExe.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
Tilda (~)
Znak tilda (~) má v PowerShellu zvláštní význam. Když se používá s příkazy PowerShellu na začátku cesty, znak tilda se rozbalí do domovského adresáře uživatele. Pokud se znak tilda používá kdekoli jinde v cestě, považuje se za literální znak.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Set-Location ~
PS C:\Users\user2> $PWD
Path
----
C:\Users\user2
V tomto příkladu očekává parametr NameNew-Item řetězec. Znak tilda se bere jako doslovný znak. Pokud chcete přejít na nově vytvořený adresář, musíte kvalifikovat cestu znakem tildy.
PS D:\temp> Set-Location ~
PS C:\Users\user2> New-Item -Type Directory -Name ~
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/6/2024 2:08 PM ~
PS C:\Users\user2> Set-Location ~
PS C:\Users\user2> Set-Location .\~
PS C:\Users\user2\~> $PWD
Path
----
C:\Users\user2\~
Pokud použijete znak tilda s nativními příkazy, PowerShell předá tilda jako literálový znak. Použití vlnovek v cestě způsobuje chyby nativních příkazů ve Windows, které nepodporují znak tilda.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Get-Item ~\repocache.clixml
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/29/2024 3:42 PM 88177 repocache.clixml
PS D:\temp> more.com ~\repocache.clixml
Cannot access file D:\temp\~\repocache.clixml