Invoke-Command with variables

Welcome Forums General PowerShell Q&A Invoke-Command with variables

Viewing 4 reply threads
  • Author
    Posts
    • #41954
      Participant
      Topics: 1
      Replies: 3
      Points: 0
      Rank: Member

      I want to pass variables to invoke-command running commands remotely. I am missing something…here is what I have

      Trying to pass a variable for the Event Log Name “System” but the error tells me that the variable $Log is null

      Cannot bind argument to parameter ‘LogName’ because it is null.
      + CategoryInfo : InvalidData: (:) [Get-EventLog], ParameterBindingValidation
      Exception
      + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Po
      werShell.Commands.GetEventLogCommand
      + PSComputerName : DC

      $Log = ‘System’
      $Session = New-PSSession -ComputerName DC -Credential $cred
      $Command = {Get-EventLog -LogName $Log -Newest 3}

      Invoke-Command -Session $Session -ScriptBlock $Command -ArgumentList $Log

      Remove-PSSession -Session $Session

      Appreciate the help….

    • #41964
      Participant
      Topics: 0
      Replies: 74
      Points: 0
      Rank: Member

      The scriptblock has it’s own variable scope like a function or another script so you have to add a param block so it knows to expect a variable. The variable names inside and outside can be the same. I make them different for my own sanity.

      • #41980
        Participant
        Topics: 1
        Replies: 3
        Points: 0
        Rank: Member

        Thank you that does work….

        I am wondering if I missed this in the PowerShell Help or if there is a gap here that needs filling… 🙂

        I did not see anything in help, or any articles online saying that scriptblocks have param blocks and that you need that so you can use the argumentlist to pass variables to invoke-command on remote machines.

        Also you said that you keep the names different for your sanity. I am not sure I am following your thinking here.
        If I keep the $LOG variable the same in the $LOG = ‘System’ as well as in the Param block and in the command….and in the argument list doesn’t that make it simpler to follow which variables you are using or having issues with?

        what is the reason you want them to be different?

        Thanks again for your help

    • #41987
      Participant
      Topics: 0
      Replies: 74
      Points: 0
      Rank: Member

      Yea the help file isn’t real clear on it but it must be in an article somewhere I know I didn’t come up with it, I’m not that smart! When executing code on remote machines you always have to keep ‘context’ in mind since each remote machine will have it’s own unique set of environmental values and properties.

      You don’t have to use a param block either, I think most folks reference variables positionally inside the scriptblock using the $Args automatic variable. Same concept as %1 in batch scripts or WScript.Arguments in vbscript.

      Example 1:

      Example 2:

      Why do I change the variable names? Just a general rule of thumb for myself anytime I’m writing a script that passes variables between scopes I should keep things clear. Mixing up values could spell trouble…

      Example 3:

    • #42147
      Participant
      Topics: 1
      Replies: 3
      Points: 0
      Rank: Member

      OK so I have taken your example to the next level…not sure if that is up or sideways 🙂

      trying to use an import command from SCCM on a remote computer with another users Creds.

      Here is the original command which works fine.

      Import-CMComputerInformation `
      -CollectionName $TargetCollection `
      -FileName $ImportFile `
      -VariableName ‘Domain’

      The $($Args[x]) variables work fine from your example…however they do not work in the script execution

      I have listed the $($Args[x]) variables in the $Command so you can see that they work, but when I try to pass it to the commands to create a new PS Drive or perform the import they do not work.
      and yes I have tried to take them out and let it run….no dice.

      Set-Location -Path C:
      $FQDN = “$Server.domain.com”

      $Session = New-PSSession `
      -ComputerName $Server `
      -Credential $cred
      $Command = {
      $($Args[0])
      $($Args[1])
      $($Args[2])
      $($Args[3])
      $($Args[4])
      New-PSDrive `
      -Name $($Args[0]) `
      -PSProvider CMSite `
      -Root $($Args[1])

      Set-Location -Path $($Args[2])

      Import-CMComputerInformation `
      -CollectionName $($Args[3]) `
      -FileName $($Args[4]) `
      -VariableName ‘Domain’

      Set-Location -Path C:
      }
      Invoke-Command `
      -Session $Session `
      -ScriptBlock $Command `
      -ArgumentList $CMSite, $FQDN, $SCCM_Site_Code, $TargetCollection, $ImportFile

      Remove-PSSession `
      -Session $Session

      Thanks again,

    • #42156
      Participant
      Topics: 0
      Replies: 74
      Points: 0
      Rank: Member

      Try using the pre blocks to post code. Let’s post again for clarity…

      I put some questions in as comments but I have a few more. At the heart of this, you’re executing Import-CMComputerInformation on both the local machine and a remote server. Are you doing this to pre-stage machines for OSD imaging? Do your site servers belong to the same hierarchy? If they are, you should only need to import them into the top level CAS then all site servers will have access to the device information. If they are not in the same hierarchy, why import the same set of computers in two separate environments? So maybe it would help to understand what your trying to accomplish? But back to the code…

      One issue I noticed was inside the $Command you attempt to connect a PSDrive. This is the infamous ‘Second-Hop’ issue and might be a PS gotcha? Don wrote a good article about it here. Essentially it means you can use stored credentials to connect to network resources directly from your local machine to a remote computer (one hop) but you can’t execute script on a remote machine that attempts to reach out to a third machine (second hop) without enabling CredSSP.

      • #42713
        Participant
        Topics: 1
        Replies: 3
        Points: 0
        Rank: Member

        This script was part of a larger function so I didn’t include all of it since there was no issue with it. I was trying to change the code to function on the remote server with invoke-command.

        Here is the whole script. It was originally meant to be interactive, now I want it to start interactively but do the work directly on the remote server with specific credentials

        The segment that needs to change is in the Process block, in the second Foreach loop where the Import-CMComputerInformation command is.

        I want to put the invoke-command here so I can use different credentials and run the process on the SCCM Site server directly.

        thanks,

Viewing 4 reply threads
  • The topic ‘Invoke-Command with variables’ is closed to new replies.