Since you're calling from PowerShell, the best option is to pass a script block to powershell.exe
, the Windows PowerShell CLI.
- However, this raises the question: why do you need to call the CLI from PowerShell to begin with, given that you could just call your
Copy-Item
command directly, without the overhead (and potential loss of type fidelity) that comes with creating another PowerShell session, via a child process.
if you still need to call the PowerShell CLI from PowerShell itself, use the following:
$today = (Get-Date).ToString('dd_MM_yyyy_HH_mm')
powershell -Command {
Copy-Item -Recurse 'C:\ABC' -Destination ('C:\ABC_' + $args[0])
} -args $today
As for what you tried:
Removing the "
around $today
in 'C:\ABC_"$today"'
would have worked too - the outer "..."
quoting would still have ensured that $today
is expanded.
What you thought of as a single string argument,
"Copy-Item -Recurse 'C:\ABC' -Destination 'C:\ABC_"$today"'"
, was passed as two arguments:
Argument 1: Verbatim Copy-Item -Recurse 'C:\ABC' -Destination 'C:\ABC_
, which, due to being a (double-)quoted token became its own argument - despite other characters immediately following it.
Argument 2: The value of $today
, immediately followed by a verbatim '
(the value of "'"
), e.g., verbatim 06_2021_11_05'
Not being able to compose a single argument from a mix of quoted and unquoted tokens if the first token happens to be quoted is a notable pitfall, discussed in detail in this answer.
When you use -Command
and pass multiple arguments, PowerShell simply joins those arguments to form a single string by placing a space between them, before interpreting the resulting string as PowerShell code.
- Therefore, your two verbatim arguments,
Copy-Item -Recurse 'C:\ABC' -Destination 'C:\ABC_
and (e.g.) 06_2021_11_05'
were ultimately interpreted as
Copy-Item -Recurse 'C:\ABC' -Destination 'C:\ABC_ 06_2021_11_05'
- note the unwanted space.
See this answer for a comprehensive overview of the PowerShell CLI (covers both powershell.exe
and pwsh
).