Running PowerShell Scripts from Cmd.exe

One of the things that people often struggle with when they try to use PowerShell scripts as targets of Scheduled Tasks, or launch PowerShell scripts from cmd.exe is the following error message:



C:\Program Files\Windows PowerShell\v1.0>powershell.exe “c:\temp\has space\test.ps1″
‘c:\temp\has’ is not recognized as a cmdlet, function, operable program, or script file.
At line:1 char:12
+ c:\temp\has  <<<< space\test.ps1


(By the way, you can speed this up by using the -noprofile parameter to powershell.exe)


This is because Powershell doesn’t natively support a parameter for a script to run.  The default command-line argument is “-command,” which defines the command as though you had typed it at the prompt.


For example:



C:\temp\monad>powershell “2+2″
4


This happens to work on script names with no spaces or quotes, as our interpreter interprets that as a command execution.  For scripts with spaces and quotes, you are doing the equivalent of:



[C:\temp]
PS:13 > c:\temp\has space\test.ps1
‘c:\temp\has’ is not recognized as a cmdlet, function, operable program, or script file.
At line:1 char:12
+ c:\temp\has  <<<< space\test.ps1
 


[C:\temp]
PS:14 > “c:\temp\has space\test.ps1″
c:\temp\has space\test.ps1


Suggestion: Did you mean to run the command in quotes?  If so, try using & “<command>”


So, the solution is:



[C:\temp]
PS:15 > & ‘C:\temp\has space\test.ps1′
Hello World


Or,



C:\temp\monad>powershell “& ‘c:\temp\has space\test.ps1′”
Hello World


This is something that we know to be a usability issue.  We’re tracking it internally, but a bug (and votes) on Ms Connect would help us prioritize this properly.

4 Responses to “Running PowerShell Scripts from Cmd.exe”

  1. David Moisan writes:

    I’m looking for the PS equivalent of:

    cd %userprofile%

    which in cmd.exe does:

    c:\Documents and Settings\Some User>

    I want to do this in PS since there are so many environment variables that are paths, such as %windir@ and %systemroot% and I can’t seem to do anything like:

    cd &Env:Systemroot to change to the path pointed by the env variable.

    gc Env:Systemroot returns C:\Windows but how do I cd there?

  2. Lee writes:

    Hi David;

    The way to access environment variables in PowerShell is "$env:SystemRoot" (no quotes needed.) The dollar sign is to reference variables, and the & sign is usually to execute something. You can find a discussion of this in the help topic, about_Environment_variable.

    I’m sorry that this sounds like magic sprinkling sugar right now — I’ll post a blog soon describing more detail about it.

  3. Mike D. writes:

    Thanks for posting this, I was looking every where to find out why my xp sched.taks/cronjob was’nt running

    C:\temp\monad>powershell "& ‘c:\temp\has space\test.ps1’"

    This detail is very poorly documented. Searched ms a bunch.
    thanks again.

  4. nipun writes:

    Hey
    Thanx for this help i was really stuck in this one, but seems like problems not leaving me, i have a powershell script which is some thing like this Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
    get-messagetrackinglog -messagesubject test | export-csv ‘D:\Documents and Settings\Administrator\Desktop\exchange2007\Book1.csv’
    well if i run this thru command prompt it runs nice n clear but when i try to run this thru code i get the following error
    Get-MessageTrackingLog : Failed to connect to the Microsoft Exchange Transport Log Search service on computer "mycompany.mycompanyv2.com". Verify that a valid computer name was used and the Microsoft Exchange Transport Log Search service is started on the target computer. The error message is: Access is denied.At D:\Documents and Settings\Administrator\Desktop\exchange2007\test.ps1:2 char:23+ get-messagetrackinglog <<<< -messagesubject test | export-csv ‘D:\Documents and Settings\Administrator\Desktop\exchange2007\Book1.csv’
    here is code snippet as well, i have provided impersonation so that the code can execute with admin rights
    string command = "powershell.exe \"& ‘D:\\Documents and Settings\\Administrator\\Desktop\\exchange2007\\test.ps1’\"";

    System.Diagnostics.ProcessStartInfo procStartInfo =
    new System.Diagnostics.ProcessStartInfo("cmd","/c "+command);

    // The following commands are needed to redirect the standard output.
    // This means that it will be redirected to the Process.StandardOutput StreamReader.
    procStartInfo.RedirectStandardOutput = true;
    procStartInfo.UseShellExecute = false;
    // Do not create the black window.
    procStartInfo.CreateNoWindow = true;
    // Now we create a process, assign its ProcessStartInfo and start it
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    try
    {
    test = Environment.UserName + " – " + this.User.Identity.Name;
    proc.Start();
    }
    catch (Exception ex)
    {

    }
    // Get the output into a string
    while (!proc.StandardOutput.EndOfStream)
    {
    result += proc.StandardOutput.ReadLine();
    }
    plz help

Leave a Reply