0

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!

8
  • have you tried cd C:\location of ps.1 and running .\thefile.ps1 ? Commented Dec 19, 2019 at 9:43
  • You would have to escape the embedded " in the first command as \". The second command looks correct (and is the better choice). When you say that nothing happens, can you be more specific? No error message? Is the script invoked at all? Commented Dec 19, 2019 at 11:55
  • Hey, I am expecting a file to be copied to a specific location, well that is not happening. Whereas when running from Powershell ISE same plot of the PS1 script it works fine... I feel that there is something that i may be missing during the Invocation from CMD Commented Dec 19, 2019 at 16:51
  • Unfortunately this gives me this error: A parameter cannot be found that matches parameter name 'Argumentlist' Commented Dec 23, 2019 at 13:51
  • 1
    Hmmmmm! first run, i am seeing results ! Gonna try it on test environment as part of a build invocation ^_^ Commented Dec 23, 2019 at 21:57

3 Answers 3

2
+50

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Will test in 7 hours
The dot, in the ". C:\ ..." is not doing anything. Its the -noexit parameter that makes it happen. Either way, you've got us the solution !
ny the way, this is working on Windows 10, but its not on Win Server 2016.....
0

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

1 Comment

Hey, thanks for the suggestion, i am intentionally running Start-Job because i need it to be asynch (i dont want to wait for it).
0

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

3 Comments

Hey, This is actually an interesting approach, yet the problem is that while using Start-Job, it seems to be not doing anything, even if the script is working good by itself (wihtout deleting it as you've mentioned). Please do try to simulate my script, that was presented in the issue desription.
Has the line #Start-Sleep -Seconds 300 been remarked out for a reason? And have you tried with powershell.exe as opposed to just powershell as you've shown in the question?
The remarked Start-Sleep will be used during an actual run, was outted so that script wont hold for 5 minutes.. I have tried powershell.exe and powershell...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.