powershellxcopy

save xcopy error message in a variable in powershell


I want to assign to a variable the error message printed by an xcopy command from a powershell script. If I simply assign the command to a variable, it only saves the last line, where it says the number of files copied

> $out = xcopy C:\test.txt C:\
File not found - test.txt
> $out
0 File(s) copied

I want to save the error message, meaning the string "File not found".

I already tried all methods suggested here How to show output of xcopy in powershell script while it's running, but also piping it to Tee-Object -Variable out only saves the last line of the output and not the error message (same as above).

The closest I got was by using redirection xcopy C:\a.txt C:\ 2>&1 | Out-Host , but this still doesn't save it to a variable of my choice, only to the global $error[0] variable

My desired output would be a string with the error message. In the above example:

> $out
File not found - test.txt

Solution

  • You should use $xcoutput = (XCOPY C:\TEST.TXT C:\ 2>&1).

    XCOPY is not a PowerShell cmdlet; it’s what is referred to as an ‘external command’ (implemented via the file XCOPY.EXE). This means that it doesn’t generate PowerShell objects as output; it generates ordinary strings.

    If you want to capture the standard output of an external command in a PowerShell variable, simply writing $xcoutput = XCOPY C:\TEST.TXT C:\ will do the trick - but XCOPY also writes to the standard error output, so in order to capture that, you need to redirect the standard error output to the standard output. This is done by XCOPY C:\TEST.TXT C:\ 2>&1 when you don’t want/need to capture it in a variable.

    However, it’s not automatically clear whether $capturevariable = XCOPY C:\TEST.TXT C:\ 2>&1 is supposed to redirect the standard error output of XCOPY to the standard output of XCOPY, or whether to redirect the standard error output of the assignment to the standard output of the assignment. The parentheses of $xcoutput = (XCOPY C:\TEST.TXT C:\ 2>&1) clarifies this, and redirects the standard error output of XCOPY to the standard output of XCOPY, then takes the combined output and assigns it to $xcoutput. $xcoutput is now an object of type [string[]], and can be manipulated as such.

    (Microsoft Learn has a whole page on PowerShell redirection.)