Powershell の -command と -argumentlist の違いは何ですか?

Powershell の -command と -argumentlist の違いは何ですか?

そこで、このファイルを Program Files にコピーしたいのですが、次のようにする必要があります (右クリックして、管理者として実行する必要があります)。

Copy-Item \\Poplar\SuperSound -Destination 'C:\Program Files\' -Force -Recurse

しかし、PowerShell スクリプトではそれが必要でした。

私が通常高める方法は次のとおりです。

powershell -command "install_bananas.bat" -Verb runas

しかし、実行すると:

powershell -command "Copy-Item \\Zuul\IT\ffmpeg -Destination 'C:\Program Files\' -Force -Recurse" -Verb runas

...エラーが発生しました:

Copy-Item : A positional parameter cannot be found that accepts argument 'runas'.

代わりに、Start-Process で -argumentlist を使用する必要があります。

Start-Process powershell -Verb runas -argumentlist "Copy-Item \\Poplar\SuperSound -Destination 'C:\Program Files\' -Force -Recurse" 

したがって、argumentlist は Start-Process でのみ使用されると思われます。

それでpowershell コマンド開始プロセス powershell -引数リストでは、次のような複数引数のコマンドを実行する必要がある場合、なぜ -Verb runas で問題が発生するのでしょうか。

Copy-Item A -Destination B

?

注: ついに Powershell の本を購入する時期が来たと思います。

答え1

本を買えば何か手に入るが、まずヘルプファイルにアクセスしてくださいなぜなら、それらは無料で、あなたの目の前にあるものだからです。 ;-}

# Get specifics for a module, cmdlet, or function
(Get-Command -Name Start-Process).Parameters
(Get-Command -Name Start-Process).Parameters.Keys
# Results
<#
FilePath
ArgumentList
Credential
WorkingDirectory
LoadUserProfile
NoNewWindow
PassThru
RedirectStandardError
RedirectStandardInput
RedirectStandardOutput
Verb
WindowStyle
Wait
UseNewEnvironment
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
#>

Get-help -Name Start-Process -Examples
# Results
<#
Start-Process -FilePath "sort.exe"
Start-Process -FilePath "myfile.txt" -WorkingDirectory "C:\PS-Test" -Verb Print
Start-Process -FilePath "Sort.exe" -RedirectStandardInput "Testsort.txt" -RedirectStandardOutput "Sorted.txt" -RedirectStandardError 
Start-Process -FilePath "notepad" -Wait -WindowStyle Maximized
Start-Process -FilePath "powershell" -Verb runAs
$startExe = New-Object System.Diagnostics.ProcessStartInfo -Args PowerShell.exe
$startExe.verbs
Start-Process -FilePath "powershell.exe" -Verb open
Start-Process -FilePath "powershell.exe" -Verb runas

#>
Get-help -Name Start-Process -Full
Get-help -Name Start-Process -Online


powershell /?
# Results
<#

PowerShell[.exe] [-PSConsoleFile <file> | -Version <version>]
    [-NoLogo] [-NoExit] [-Sta] [-Mta] [-NoProfile] [-NonInteractive]
    [-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
    [-WindowStyle <style>] [-EncodedCommand <Base64EncodedCommand>]
    [-ConfigurationName <string>]
    [-File <filePath> <args>] [-ExecutionPolicy <ExecutionPolicy>]
    [-Command { - | <script-block> [-args <arg-array>]
                  | <string> [<CommandParameters>] } ]

...

-Command
    Executes the specified commands (and any parameters) as though they were
    typed at the Windows PowerShell command prompt, and then exits, unless 
    NoExit is specified. The value of Command can be "-", a string. or a
    script block.

    If the value of Command is "-", the command text is read from standard
    input.

    If the value of Command is a script block, the script block must be enclosed
    in braces ({}). You can specify a script block only when running PowerShell.exe
    in Windows PowerShell. The results of the script block are returned to the
    parent shell as deserialized XML objects, not live objects.

    If the value of Command is a string, Command must be the last parameter
    in the command , because any characters typed after the command are 
    interpreted as the command arguments.

    To write a string that runs a Windows PowerShell command, use the format:
    "& {<command>}"
    where the quotation marks indicate a string and the invoke operator (&)
    causes the command to be executed.

...
#>

Start-Process (Microsoft.PowerShell.Management ... https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7

パラメーター

-ArgumentList このコマンドレットがプロセスを開始するときに使用するパラメーターまたはパラメーター値を指定します。引数は、スペースで区切られた単一の文字列として、またはコンマで区切られた文字列の配列として受け入れられます。

パラメータまたはパラメータ値にスペースが含まれている場合は、エスケープされた二重引用符で囲む必要があります。詳細については、「about_Quoting_Rules」を参照してください。

コマンドレット経由でコマンドを実行することと、powershell.exe 経由でコマンドを実行することは、2 つの異なることです。それぞれに引用符の詳細があります。必要な引用符を含む構文が正しくないため、このようなエラーが発生します。

したがって、あなたのユースケースでは、Start-Process は次のようになります。

$ConsoleCommand = "Copy-Item \\Zuul\IT\ffmpeg -Destination 'C:\Program Files\' -Force -Recurse"
Start-Process powershell -ArgumentList '-NoExit',"-Command  &{ $ConsoleCommand }" 

PowerShell.exe の場合、次のようになります。

PowerShell -Command {Copy-Item \\Zuul\IT\ffmpeg -Destination 'C:\Program Files\' -Force -Recurse}

あるいはこれ

PowerShell -Command "& {Copy-Item \\Zuul\IT\ffmpeg -Destination 'C:\Program Files\' -Force -Recurse}"

これらを組み合わせることができます。たとえば、ISE/VScode 内にいるときに、ISE/VSCode 内に留まりながら新しいインスタンスにコマンドを実行したい場合は、次のようになります。

Function Start-ConsoleCommand
{
    [CmdletBinding(SupportsShouldProcess)]

    [Alias('scc')]

    Param  
    ( 
        [string]$ConsoleCommand,
        [switch]$PoSHCore
    )

    If ($PoSHCore)
    {Start-Process pwsh -ArgumentList "-NoExit","-Command  &{ $ConsoleCommand }" -Wait}
    Else
    {Start-Process powershell -ArgumentList "-NoExit","-Command  &{ $ConsoleCommand }" -Wait}

}

関連情報