1

I am executing the below script on the windows server as a PowerShell script -

$today = (Get-Date).ToString('dd_MM_yyyy_HH_mm')
echo "Date & Time : $today"

powershell -Command "Copy-Item -Recurse 'C:\ABC' -Destination 'C:\ABC_"$today"'"

The above script is working fine but there is a blank space between ABC & Date while creating the directory. Please please help me on this how can I remove this blank space.

**Directory Name :** ModelFactoryProducti**on_ 28**_06_2021_11_05
**Directory Name Should be :** ModelFactoryProduction_28_06_2021_11_05
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • 1
    You tagged this question as powershell 2 **and** 3. It probably doesn't matter here, but if you specify a version, then please specify only the version you are using. – Socowi Jun 28 '21 at 19:30
  • 3
    to remove that unwanted space, remove the unneeded quotes around the `$Today` variable AND replace the single, outer quotes with double quotes.. ///// also, you REALLY otta use a sortable date format. the silly day/month/year thing is ... silly. instead, use year/month/day to get a sane, sensible, SORTABLE string value. [*grin*] – Lee_Dailey Jun 28 '21 at 19:44
  • 1
    Good point about needing to remove the `"` around `$today`, @Lee_Dailey, but that is all that is needed, given that the immediately enclosing `'...'` string is itself embedded in a larger, expandable `"..."` string. – mklement0 Jun 28 '21 at 22:37
  • @mklement0 - yep ... but the nested quotes is where the space is coming from. i have no idea WHY ... but a simple test shows that unwanted space. my suggestion to the OP is to build the whole string ahead of time. – Lee_Dailey Jun 28 '21 at 23:26
  • @Lee_Dailey, my answer explains where the space is coming from. – mklement0 Jun 28 '21 at 23:42
  • 1
    @mklement0 - oooo! thank you for pointing that out to me ... i was wondering about it ... [*grin*] – Lee_Dailey Jun 29 '21 at 00:45

2 Answers2

1

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).

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Use the following:

$today = (Get-Date -format 'dd_MM_yyyy_HH_mm')
Copy-Item -Recurse 'C:\ABC' -Destination "C:\ABC_$today"

When possible, avoid using either of these kinds of syntax, as it's very simple to allow accidentally (or maliciously) inserting extra data into the command string. Plus, you're already in powershell - no need to execute powershell again unless you left it to run some cmd commands:

powershell -c "Write-Host $var"
Invoke-Expression -Command 'Write-Host "$var"'
Cpt.Whale
  • 4,784
  • 1
  • 10
  • 16