Execute “real life” command line from variable in Powershell

前端 未结 3 607
暗喜
暗喜 2020-12-10 21:36

When I for example read some uninstall string from the registry like \"C:\\Program Files (x86)\\Opera\\Launcher.exe\" /uninstall I can copy it to the Powershell

3条回答
  •  难免孤独
    2020-12-10 22:24

    In order to use & (or direct invocation if the command name/path is an unquoted literal), the command name/path must be passed separately from its arguments.
    When invoking an external program, you may pass these arguments as an array.

    The solution below leverages PowerShell's own Write-Output cmdlet in combination with a - safe - invocation of Invoke-Expression[1] in order to parse the string into its constituent arguments.

    # Gets the arguments embedded in the specified string as an array of literal tokens 
    # (applies no interpolation). 
    # Note the assumption is that the input string contains no NUL characters 
    # (characters whose code point is `0x0`) - which should be a safe assumption
    # Example: 
    #   get-EmbeddedArguments '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
    # yields array @( 'C:\Program Files (x86)\Opera\Launcher.exe', '/uninstall' )
    function get-EmbeddedArguments ([string] $String) {
      (Invoke-Expression "Write-Output -- $($String -replace '\$', "`0")") -replace "`0", '$'            #"
    }
    
    # Input string.
    $var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
    
    # Extract the command name (program path) and arguments.
    # Note the destructuring assignment that stores the return array's 1st element
    # in $exe, and collects the remaining elements, if any, in $exeArgs.
    $exe, $exeArgs = get-EmbeddedArguments $var
    
    # Use & to invoke the command (name / program path) ($exe) and pass
    # it all arguments as an array.
    & $exe $exeArgs
    

    [1] Invoke-Expression should generally be avoided, as Bill points out, because it presents a security risk and there are typically safer and more robust options available. Here, however, there is no simple alternative, and the security risk is avoided by temporarily replacing all $ instances in the input string so as to prevent unintended string interpolation.

提交回复
热议问题