简体   繁体   中英

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!

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

点源它,这将更改您的作业的源函数的范围,使其在当前运行的脚本的范围内工作,同时还允许您运行多个线程。

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 
#######################################################################

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM