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.