Ilya Gurenko
Ilya Gurenko

Reputation: 565

run PowerShell script from CMD (tricky one)

I know this may sound like a question that was here before (and partially it will be true). Yet i have an interesting twist here.

Needed flow:
run Powershell script from CMD. Seems trivial, and is actually working, with passing parameters etc...
But ...
My powershell script has a Start-Job with in it, as i want it to run async.

#######################################################################

   #$DropLocation = "SOME UNC PATH"
   #$buildid = "SOME VERSION"
param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 


Start-Job -Name Upload `
-ScriptBlock {

param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 
Write-Output "asd"
$buildpath = $DropLocation+"\"+$buildid
$logs = gci $buildpath"\logs" -Name "ActivityLog.AgentScope*.xml"

#Start-Sleep -Seconds 300

if ($logs.PSPath -gt 0)
    { 
        $destination = $env:TEMP+"\Config\"
        Copy-Item $logs.PSPath "$destination $buildid.xml"
    }
} `
-ArgumentList $DropLocation,$buildid

#######################################################################

I am using Param to intake from outside, and then once again in the Start-Job so that the Async job get its params

This script is saved as SCRIPTNAME.ps1 and i am trying to run it from CMD.

From cmd (running as admin)

powershell "& "C:\temp\SCRIPTNAME.ps1" "SOME UNC PATH" "SOME VERSION""

or

powershell -file "C:\temp\SCRIPTNAME.ps1" "SOME UNC PATH" "SOME VERSION"

Nothing happens.
Yet from the PowerShell ISE all is working well

Assistance is more than appreciated!

Upvotes: 0

Views: 802

Answers (3)

shadow2020
shadow2020

Reputation: 1351

powershell -noexit ". C:\temp\SCRIPTNAME.ps1"

Dot source it, this will change the scope of the sourced function for your job to work within the currently running script's scope while allowing you to run multiple threads also.

Upvotes: 2

T3RR0R
T3RR0R

Reputation: 2951

Without knowing the Profile / Policy configuration of the environment, Might I suggest Invoking with the profile / policy modifiers in the example below? Sometimes they can make all the difference to executing powershell from batch

Have you tried writing generating and executing the powershell script from within Batch

Whenever I need powershell to do something cmd can't, I write the script as a function I can call from within the batch file.

Here's an example of my approach:

:createshortcut
(
ECHO # Create a Shortcut with Windows PowerShell
ECHO $SourceFileLocation = "%ShortcutTargetPATH%"
ECHO $ShortcutLocation = "%userprofile%\Desktop\%shortcutname%.Ink"
ECHO #New-Object : Creates an instance of a Microsoft .NET Framework or COM object.
ECHO #-ComObject WScript.Shell: This creates an instance of the COM object that             
represents the WScript.Shell for invoke CreateShortCut
ECHO $WScriptShell = New-Object -ComObject WScript.Shell
ECHO $Shortcut = $WScriptShell.CreateShortcut($ShortcutLocation^)
ECHO $Shortcut.TargetPath = $SourceFileLocation
ECHO $Shortcut.IconLocation = "%IconPATH%\%IconNameEXT%"
ECHO #Save the Shortcut to the TargetPath
ECHO $Shortcut.Save(^)
) >%AppDataPATH%\%PowerShellnameEXT%

TIMEOUT 1 >nul

Powershell.exe -NoProfile -ExecutionPolicy Bypass -File %AppDataPATH%\%PowerShellnameEXT%

TIMEOUT 1 >nul

DEL /Q "%AppDataPATH%\%PowerShellnameEXT%"

GOTO :EOF

Set the values required for the scripts execution & then Just call the Function. The key thing to remember when using this approach is to Escape the appropriate characters when writing the .ps1 file

Upvotes: 0

Sage Pourpre
Sage Pourpre

Reputation: 10323

My take on your issue, based on the provided script, is that your script exit before the job completion.

--

Here's both behavior side-to-side

ISE / VSCode

  • Script is launched
  • Start-Job is called
  • Script complete
  • Job complete

CMD

  • Script is launched through cmd
  • Start-Job is called
  • Script complete
  • Powershell session is terminated (and job execution killed)
  • Job never complete

To prevent the session from being killed until the job complete, add the following line at the end of your script Receive-Job -Name 'upload' -Wait

Here's the new script with that modification.

#######################################################################

   #$DropLocation = "SOME UNC PATH"
   #$buildid = "SOME VERSION"
param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 


Start-Job -Name Upload `
-ScriptBlock {

param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 
Write-Output "asd"
$buildpath = $DropLocation+"\"+$buildid
$logs = gci $buildpath"\logs" -Name "ActivityLog.AgentScope*.xml"

#Start-Sleep -Seconds 300

if ($logs.PSPath -gt 0)
    { 
        $destination = $env:TEMP+"\Config\"
        Copy-Item $logs.PSPath "$destination $buildid.xml"
    }
} `
-ArgumentList $DropLocation,$buildid

# Prevent the session to be killed before the job return.
Receive-Job -Name 'upload' -Wait 
#######################################################################

Upvotes: 0

Related Questions