Workflow and InlineScript

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
sekou2331
Posts: 267
Joined: Wed Aug 15, 2012 6:07 am

Workflow and InlineScript

Post by sekou2331 » Tue Nov 19, 2019 3:16 pm

Hi,

I am trying to use workflow to run a python script on different machines. I am doing this because each run takes a long time to complete so I need to run it parallel. I am using the script below. It works if I write out the path but I need to be able to check the path before using it. So I am using another function to do this. The only issue is when I use the other function and then use $using: it makes the arg the path for some reason. I looked around but I cant seem to determine if you can use $using: twice in a Inlinescript. This is the error I am getting.
  1. ERROR: C:\Python27\python.exe: can't open file 'TheArg': [Errno 2] No such file or directory
  2.  
  3. ERROR:     + CategoryInfo          : NotSpecified: (C:\Python27\pyt...le or directory:String) [], RemoteException
  4.  
  5. ERROR:     + FullyQualifiedErrorId : NativeCommandError
  6.  
  7. ERROR:     + PSComputerName        : [localhost]
  8.  
  9. ERROR:
  10.  
  11. ERROR: C:\Python27\python.exe: can't open file 'TheArg': [Errno 2] No such file or directory
  12.  
  13. ERROR:     + CategoryInfo          : NotSpecified: (C:\Python27\pyt...le or directory:String) [], RemoteException
  14.  
  15. ERROR:     + FullyQualifiedErrorId : NativeCommandError
  16.  
  17. ERROR:     + PSComputerName        : [localhost]
  18.  
  19. ERROR:
  20.  
  21. ERROR: C:\Python27\python.exe: can't open file 'TheArg': [Errno 2] No such file or directory
  22.  
  23. ERROR:     + CategoryInfo          : NotSpecified: (C:\Python27\pyt...le or directory:String) [], RemoteException
  24.  
  25. ERROR:     + FullyQualifiedErrorId : NativeCommandError
  26.  
  27. ERROR:     + PSComputerName        : [localhost]
  28.  
  29. ERROR:
  30.  
  31. ERROR: C:\Python27\python.exe: can't open file 'TheArg': [Errno 2] No such file or directory
  32.  
  33. ERROR:     + CategoryInfo          : NotSpecified: (C:\Python27\pyt...le or directory:String) [], RemoteException
  34.  
  35. ERROR:     + FullyQualifiedErrorId : NativeCommandError
  36.  
  37. ERROR:     + PSComputerName        : [localhost]

  1. function Get-TruePath {
  2.  
  3.     param
  4.  
  5.     (
  6.  
  7.         [Parameter(Mandatory = $true)]
  8.  
  9.         $server
  10.  
  11.     )
  12.  
  13.     $verifyPathShare = Get-WMIObject -ComputerName ('{0}' -f $server) -Query 'SELECT * FROM Win32_Share' | Where-Object -Property Name -eq 'Share'
  14.  
  15.     $tritonTSFPath = 'PartofPath\MyFile.py'
  16.  
  17.     $foundPath = Join-Path -Path $verifyPathShare.Path -ChildPath $tritonTSFPath
  18.  
  19.    
  20.  
  21.     $foundPath
  22.  
  23. }
  24.  
  25.  
  26.  
  27.  
  28.  
  29. workflow foreachptest {
  30.  
  31.     param ([string[]]$computers)
  32.  
  33.     foreach –parallel ($computer in $computers) {
  34.  
  35.         $a = Get-TruePath -server $computer
  36.  
  37.        
  38.  
  39.         InlineScript { Invoke-Command -Computer $using:computer -ArgumentList 'TheArg' -Scriptblock { python.exe ${$using:a} $args[0]  } }
  40.  
  41.        
  42.  
  43.        
  44.  
  45.     }
  46.  
  47.    
  48.  
  49. }
  50.  
  51.  
  52.  
  53. foreachptest -computers 'Computername', 'Computername', 'Computername', 'Computername'

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Tue Nov 19, 2019 3:26 pm

You cannot call an external function in a workflow.

You do not want to check a path like this since it is on the remote computer. The function does not return a valid share name. It returns an object with all share properties and the "Where" does nothing useful.

To get a share path you will need to use both the actual share name and extract the path:

$path = (Get-WmiObject Win32_Share -Filter "Name='sharename'").Path

User avatar
sekou2331
Posts: 267
Joined: Wed Aug 15, 2012 6:07 am

Re: Workflow and InlineScript

Post by sekou2331 » Tue Nov 19, 2019 4:46 pm

Ok how do I get the inlinescript to use using twice?

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Tue Nov 19, 2019 5:50 pm

I think you should start by fixing all of your workflow. Pass elements to Invoke-Command in the ArgumentList.

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Tue Nov 19, 2019 6:01 pm

This would be closer to what you are trying to do.

Code: Select all

workflow foreachptest{
    param (
        [string[]]$computers
    )

    foreach –parallel ($computer in $computers){
        $sharePath = (Get-WMIObject Win32_Share -ComputerName $computer -Filter "Name='Share'").Path + '\PartofPath\MyFile.py'

        InlineScript{
            Invoke-Command -ArgumentList $sharePath,'TheArg' -Scriptblock {python.exe $args[0] $args[1]} -Computer $using:computer 
        }
    }
}

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Tue Nov 19, 2019 6:10 pm

This would be even more efficient:

Code: Select all

workflow foreachptest{
    param (
        [string[]]$computers
    )

    foreach –parallel ($computer in $computers){
        InlineScript{
            $sharePath = (Get-WMIObject Win32_Share -Filter "Name='ShareName'").Path + '\PartofPath\MyFile.py'
            Invoke-Command -ArgumentList 'TheArg' -Scriptblock {python.exe $sharePath $args[1]} -Computer $using:computer 
        }
    }
}

User avatar
sekou2331
Posts: 267
Joined: Wed Aug 15, 2012 6:07 am

Re: Workflow and InlineScript

Post by sekou2331 » Wed Nov 20, 2019 7:14 am

Hi for the first example I am getting this error:
ERROR: C:\Python27\python.exe: can't open file 'GroupMain': [Errno 2] No such file or directory
ERROR: + CategoryInfo : NotSpecified: (C:\Python27\pyt...le or directory:String) [], RemoteException
ERROR: + FullyQualifiedErrorId : NativeCommandError
ERROR: + PSComputerName : [localhost]
ERROR:


For the second one I am getting nothing. So I changed $args[1] to $args[0] and I get this error.
ERROR: Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then
ERROR: try the command again.
foreachptest (6, 6): ERROR: At Line: 6 char: 6
ERROR: +
ERROR: + CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
ERROR: + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
ERROR: + PSComputerName : [localhost]
ERROR:
ERROR: Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then
ERROR: try the command again.

The funny thing is if I use the below it works with no issue but I am unable to check the share path
  1. workflow foreachptest{
  2.  
  3.     param (
  4.  
  5.         [string[]]$computers
  6.  
  7.     )
  8.  
  9.  
  10.  
  11.     foreach –parallel ($computer in $computers){
  12.  
  13.        #$sharePath = (Get-WMIObject Win32_Share -ComputerName $computer -Filter "Name='NAME'").Path + '\PartofPath\MyFile.py'
  14.  
  15.         InlineScript{
  16.  
  17.        
  18.  
  19.             $sharePath = 'D:\PartofPath\MyFile.py'
  20.  
  21.             Invoke-Command -ArgumentList $sharePath,'TheArg'  -Scriptblock {python.exe $args[0] $args[1]} -Computer $using:computer
  22.  
  23.         }
  24.  
  25.     }
  26.  
  27. }
  28.  
  29. foreachptest -computers 'Computername1', 'Computername2', 'Computername3', 'Computername4'

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Wed Nov 20, 2019 7:49 am

Can you please fix you post so the code is properly formatted. I cannot read or copy it correctly.

jvierra
Posts: 14009
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Workflow and InlineScript

Post by jvierra » Wed Nov 20, 2019 7:53 am

Sorry - I typed the above example incorrectly.

Code: Select all

workflow foreachptest{
    param (
        [string[]]$computers
    )

    foreach –parallel ($computer in $computers){
        InlineScript{
            $sb = {
                $sharePath = (Get-WMIObject Win32_Share -Filter "Name='ShareName'").Path + '\PartofPath\MyFile.py'
                python.exe $sharePath $args[0]
            }
            Invoke-Command -ArgumentList 'TheArg' -Scriptblock $sb -Computer $using:computer 
        }
    }
}

User avatar
sekou2331
Posts: 267
Joined: Wed Aug 15, 2012 6:07 am

Re: Workflow and InlineScript

Post by sekou2331 » Wed Nov 20, 2019 8:44 am

This works Thanks! Sorry about the formatting. Quick question. If I put the server name in a file and use GC it looks like workflow does not run parallel. Is there a way to pass a file full over servers into memory and then hand it to the workflow function. Because I am thinking that GC is handing the server names one at a time instead of all at once.

Post Reply