Home > Net >  Invoke-command and running ps1 with parameters
Invoke-command and running ps1 with parameters

Time:02-25

I'm trying to run a script using invoke-command to install defender for endpoint with some associated parameters.

If I run a standard ps1 using invoke-command it works with no issues. However, if I run the following:

Invoke-Command -ComputerName NAME -FilePath \\srv\share\install.ps1 -OnboardingScript \\srv\share\WindowsDefenderATPonboardingscript.cmd -Passive

I receive "A parameter cannot be found that matches parameter name 'OnboardingScript'". Can someone please help me understand how I invoke a command and run a script with parameters?

Parameters already defined in the install.Ps1 file

https://github.com/microsoft/mdefordownlevelserver/blob/main/Install.ps1

Many thanks in advance

CodePudding user response:

Your Invoke-Command call has a syntax problem, as Santiago Squarzon points out:

Any pass-through arguments - those to be seen by the script whose path is passed to -FilePath - must be specified via the -ArgumentList (-Args) parameter, as an array.

# Simplified example with - of necessity - *positional* arguments only.
# See below.
Invoke-Command -ComputerName NAME -FilePath .\foo.ps1 -Args 'bar', 'another arg'

The same applies to the more common invocation form that uses a script block ({ ... }), via the (potentially positionally implied) -ScriptBlock parameter.

However, there's a catch: Only positional arguments can be passed that way, which:

  • (a) requires that the target script support positional argument binding for all arguments of interest...

  • (b) ... which notably precludes passing switch parameters (type [switch]), such as -Passive in your call.

  • (c) requires you to pass the invariably positional arguments in the correct order.


Workaround:

Use a -ScriptBlock-based invocation, which allows for regular argument-passing with the usual support for named arguments (including switches):

  • If, as in your case, the script file is accessible by a UNC path visible to the remote session as well, you can simply call it from inside the remote script block.
  • Note: It isn't needed in your case, but you generally may need $using: references in order to incorporate values from the local session into the arguments - see further below for an example.
Invoke-Command -ComputerName NAME {
  & \\srv\share\install.ps1 -OnboardingScript \\srv\share\WindowsDefenderATPonboardingscript.cmd -Passive
} 
  • Otherwise (typically, a script file local to the caller):

Use a $using: reference to pass the content (source code) of your script file to the remote session, parse it into a script block there, and execute that script block with the arguments of interest :

$scriptContent = Get-Content -Raw \\srv\share\install.ps1
Invoke-Command -ComputerName NAME {
  & ([scriptblock]::Create($using:scriptContent)) -OnboardingScript \\srv\share\WindowsDefenderATPonboardingscript.cmd -Passive
} 

Small caveat: Since the original script file's source code is executed in memory in the remote session, file-related reflection information won't be available, such as the automatic variables that report a script file's full path and directory path ($PSCommandPath and $PSScriptRoot).

That said, the same applies to use of the -FilePath parameter, which essentially use the same technique of copying the source code rather than a file to the remote session, behind the scenes.

CodePudding user response:

thanks for your reply. I have managed to get this working by adding -ScriptBlock {. "\srv\share etc}

  • Related