0

I'm trying to make a GUI with PowerShell so it's easier to manipulate scanstate.exe with the different xml files.

However, when I try to execute it, nothing really happens. I'm giving the right location but it can't seem to find it.

    Start-Process : This command cannot be run due to the error: The system cannot find the file specified.
    At C:\DigiTool\DigiTool.ps1:1266 char:129
    + ...             Start-Process -FilePath $c -ArgumentList $arglist -Wait - ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOperationException
        + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

I'm probably doing something wrong with the parameters I'm giving along. But I'm not sure what.

$c = Split-Path -Path $PSCommandPath
$c = (Join-Path $c "USMT\amd64\scanstate.exe")
Write-Host "$c"
Write-Host "$arglist"
Start-Process -FilePath $c -ArgumentList $arglist -Wait -PassThru                                                                                                                               
mklement0
  • 382,024
  • 64
  • 607
  • 775
Pascal D.
  • 21
  • 5

2 Answers2

0

I found a way around my problem with calling cmd directly and passing the command.

Start-Process cmd.exe -WorkingDirectory $dir -ArgumentList { /k scanstate.exe G:\a_ex03505\10.28.19-14.55.37 /ue:** /ui:$user /o /c /i:Custom\MigAppO2019.xml /i:Custom\MigUser_Including_Downloads.xml /i:Migdocs.xml /i:Custom\ExcludeSystemFolders.xml /i:Custom\ExcludeDrives_D_to_Z.xml /i:Custom\ExcludeOneDriveUserFolders.xml}

Matthew
  • 1,412
  • 2
  • 20
  • 35
Pascal D.
  • 21
  • 5
  • Aside from `cmd.exe` not being required and possibly also not `Start-Process` (unless you need the command to run in a _new window_), I suggest not using script blocks `{ ... }` to pass an argument to the `[string]`-typed `-ArgumentList` parameter: While convenient from a quoting perspective, it creates the mistaken impression that you can use variables or expressions inside the script block, which doesn't work in this scenario. – mklement0 Oct 28 '19 at 16:27
0

Here's the efficient, PowerShell-idiomatic way to invoke your command synchronously, in the same console window, with output connected to PowerShell's streams:

# Determine the executable's file path.
$c = Join-Path $PSScriptRoot 'USMT\amd64\scanstate.exe'

# Note how &, the call operator is needed for invocation, because the
# executable path is stored in a *variable* (the same would apply if
# a *quoted* string were used).
& $c G:\a_ex03505\10.28.19-14.55.37 /ue:*\* /ui:$user /o /c /i:Custom\MigAppO2019.xml /i:Custom\MigUser_Including_Downloads.xml /i:Migdocs.xml /i:Custom\ExcludeSystemFolders.xml /i:Custom\ExcludeDrives_D_to_Z.xml /i:Custom\ExcludeOneDriveUserFolders.xml

If you need to run the command in a given working directory:

Push-Location $dir

# Note how scanstate.exe, assumed to be located in $dir,
# must be invoked as .\scanstate.exe - with a path component that explicitly
# references the current dir. - in order to be executed from there.
# 
# By design, for security reasons, PowerShell doesn't execute
# executables in the current dir. by file name only - that only works
# for executables in the system's path (dirs. listed in $env:PATH).
.\scanstate.exe G:\a_ex03505\10.28.19-14.55.37 /ue:*\* /ui:$user /o /c /i:Custom\MigAppO2019.xml /i:Custom\MigUser_Including_Downloads.xml /i:Migdocs.xml /i:Custom\ExcludeSystemFolders.xml /i:Custom\ExcludeDrives_D_to_Z.xml /i:Custom\ExcludeOneDriveUserFolders.xml

Pop-Location

That is, the above invokes scanstate.exe in the current console window and waits for it to finish, passing its output through - though with the option to capture / relay / redirect the output for further processing (e.g., $output = scanstate.exe ... / scanstate.exe | ForEach-Object { ... }, scanstate.exe 2>$null)

  • You only need Start-Process if you want run the command in a new, separate console window.

    • Note that this won't work on Unix-like platform with PowerShell Core, where -NoNewWindow is invariably implied.
  • Console applications never require cmd.exe for execution - PowerShell is itself a shell, just like cmd.exe, so let it handle the invocation, as shown above.

For more information, see this answer.


You state that in your use case the console window is hidden, so if you need the command to run visibly, you indeed need Start-Process in order to run the command in a new window:

Start-Process -WorkingDirectory $dir scanstate.exe 'G:\a_ex03505\10.28.19-14.55.37 /ue:*\* /ui:$user /o /c /i:Custom\MigAppO2019.xml /i:Custom\MigUser_Including_Downloads.xml /i:Migdocs.xml /i:Custom\ExcludeSystemFolders.xml /i:Custom\ExcludeDrives_D_to_Z.xml /i:Custom\ExcludeOneDriveUserFolders.xml'

Note the use of a single, literal string ('...') to pass all arguments, which implicitly binds to the -ArgumentList parameter.

Add -Wait to wait for the new window to close.

mklement0
  • 382,024
  • 64
  • 607
  • 775