Background
This is a stupid problem to have, but I have it.
I created a long folder name that has a space between two words.
PowerShell Script
#Set-StrictMode #Establishes and enforces coding rules in expressions, scripts, and script blocks. #https://technet.microsoft.com/en-us/library/hh849692.aspx set-strictmode -version 1.0 $user = [Environment]::UserName $strLog = "Hello {0}" -f $user Write-Host $strLog
Error
Now when I try to run to run a power script, I get an error message:
Syntax:
powershell "c:\hello world\helloworld.ps1"
Error Message:
Textual:
c:\hello : The term 'c:\hello' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + c:\hello world\helloworld.ps1 + ~~~~~~~~ + CategoryInfo : ObjectNotFound: (c:\hello:String) [], CommandNot FoundException + FullyQualifiedErrorId : CommandNotFoundException
Solution
With Single Quotes (does not work)
Script
set dirCurrent=%CD% powershell -Command '%dirCurrent%\helloworld1.ps1'
Output:
Explanation:
Nada. No error message.
With & (works)
Idea
Let us use the ampersand & and enclose our payload in single quotes
Script
set dirCurrent=%CD% powershell -Command "& '%dirCurrent%\helloworld.ps1' "
Output:
With %~dpn0 (works)
Concept
Batch files have a special tag (%~dpn0) that allows use to get path (p), name of the calling script (n0)
And, so if we name our command script (helloworld.cmd); notice that both our invoking script and our calling script share the same name; albeit with different extension (.cmd and .ps1 respectively).
Script
rem command file and powershell share same file name rem different extension (.cmd and .ps1) and so we can rem use %~dpn0 powershell -Command "& '%~dpn0.ps1' "
Output:
Command Line Arguments
Similar care occurs when we need to pass in command line arguments and the arguments possibly reference folders \ files with spaces.
Here are the files that we will use for this example.
|
sarai.txt
sarai was here.
readFileContent.ps1
param($filename = $(throw "You must specify a file")) #Set-StrictMode set-strictmode -version 1.0 [string] $strContent = $null; $strContent = Get-Content $filename Write-Host $strContent
readFileContent.cmd
set dirCurrent=%CD% powershell -Command "& '%dirCurrent%\readFileContent.ps1'" %dirCurrent%\sarai.txt
Output:
Image:
Textual:
Get-Content : Cannot find path 'C:\hello' because it does not exist. At C:\hello world\readFileContent.ps1:9 char:15 + $strContent = Get-Content $filename + ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\hello:String) [Get-Content], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Remediate:
To fix, enclose in single and double-quotes :
readFileContentRevised.cmd
set dirCurrent=%CD% powershell -Command "& '%dirCurrent%readFileContent.ps1'" "'%dirCurrent%\sarai.txt'"
Quick Explanation:
- The Powershell script file name should be prefixed with & and surrounded in double and single quotes
- Command line arguments that reference files in the folder should be surrounded in double and single quotes; note no need for &, as that is only needed to expand scripts
Crediting ss64.com
Here is what make this whole thing work:
Call Operator
http://ss64.com/ps/call.html
The call operator (&) allows you to execute a command, script or function.
Many times you can execute a command by just typing its name, but if the command (or the path) contains a space then this will fail.
Putting the command in quotes would make PowerShell treat it as a string, so in addition to quotes, use the call operator to force PowerShell to treat the string as a command to be executed.
Syntax & "[path] command" [arguments] Key: command An executable filename (.exe), script or function. arguments The call operator will only handle a single command. Any arguments may follow the called command. If the pathname contains spaces, place the command inside double quotes and any arguments outside the quotes.
Dedicated
Dedicated to the great Dean Smith.
Like they say in Carolina, “If God is not a Carolina fan, why is the sky Carolina Blue“.