Daniel Lindegaard
Daniel Lindegaard

Reputation: 611

Invoke-Command and Enter-PSsession - Diffrences

What is the difference in between Invoke-command and Enter-PSsession here?

Hello all

I'm trying to figure out what is going on with invoke-Command and Enter-PSsession in my Powershell script. I run the same code both pleases, but in my Invoke-Command I get a error message.

What is the code designed to do:

This code is a piece of a larger controller, we use for our 1'st line support to create Shares on our file server. This bit is written as a part of the controller, and it is a direct copy of the originals controller. The top variables are only for the script to work, and is set in to illustrate the issue, and troubleshoot it.

My research have lead to, that my issue is with the last 3 lines, showed below, as it runs in Invoke-Command. I can not see why it, do no work in Invoke-command, as it works fine in a PSsession.

I guess that it's something with passing Credential a second time, but then it should also give an error in PSsession. If this is not correct, please explain why :-)

$ACL = New-Object System.Security.AccessControl.FileSystemAccessRule($($usergroup.SamAccountName), "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
$RootACL.AddAccessRule($ACL)
Set-Acl -Path $Path$sharename -AclObject $RootACL -ErrorAction 'Stop'

My code for Enter-Pssesscion: (Working)

This code is being run, after I have entered the PSsession (with Enter-PSsession -computername Server 1 -Credential $Credential) on the remote server.

$Credential = (Get-Credential -Credential user1)

 ## For test only - Below ##
 $PSComputerName = "server1"
 $Drive = "e:\"
 $DriveLetter = ($Drive -split ":")[0]
 $Usergroup = Import-Clixml -Path "C:\UserGroup.xml"
 $Path = "\\$PSComputerName\$DriveLetter$\"
 $Sharename = "User1test" #$textbox1.Text
 $users = "user1","User2"
 ## For test only - Above ##

    if (-not (Test-Path -Path ($Drive + $Sharename)))
    {
        New-Item -ItemType directory -Path ($Drive + $Sharename) -ErrorAction 'Stop' | Out-Null
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }
    Else
    {
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }


    $ACL = New-Object System.Security.AccessControl.FileSystemAccessRule($($usergroup.SamAccountName), "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
    $RootACL.AddAccessRule($ACL)
    Set-Acl -Path $Path$sharenavn -AclObject $RootACL -ErrorAction 'Stop'

My code for invoke-command: (Not working)

$Credential = (Get-Credential -Credential user1)

$PSComputerName = "server1"
$Drive = "e:\"
$DriveLetter = ($Drive -split ":")[0]
$Usergroup = Import-Clixml -Path "I:\9514 - Drift\Powershell Scripts\Project\Oprydning af Shares og AD grupper\CreateFileShare\UserGroup.xml"
$Path = "\\$PSComputerName\($DriveLetter)$\"
$sharename = "User1test" #$textbox1.Text
$users = "user1","user2"

Invoke-Command -ScriptBlock {
    param (
        [String]$Sharename,
        [String]$Drive
    )
    if (-not (Test-Path -Path ($Drive + $Sharename)))
    {
        New-Item -ItemType directory -Path ($Drive + $Sharename) -ErrorAction 'Stop' | Out-Null
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }
    Else
    {
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }


    $ACL = New-Object System.Security.AccessControl.FileSystemAccessRule($($usergroup.SamAccountName), "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
    $RootACL.AddAccessRule($ACL)
    Set-Acl -Path $Path$sharename -AclObject $RootACL -ErrorAction 'Stop'
} -ComputerName $PSComputerName -ArgumentList $sharename,$Drive,$Usergroup -Credential:$Credential -ErrorAction 'Stop'

I get the following error:

Exception calling ".ctor" with "5" argument(s): "Value cannot be null.
Parameter name: identity"

At C:\Script.ps1:11 char:1
+ Invoke-Command -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
    + PSComputerName        : Server1

Upvotes: 1

Views: 2140

Answers (1)

Jower
Jower

Reputation: 575

This is the offending line

   $ACL = New-Object System.Security.AccessControl.FileSystemAccessRule($($usergroup.SamAccountName), "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")

Seems that the $($usergroup.SamAccountName) contains null.

This is because, when sending the parameters in ArgumentList you cannot use the name of the variable outside the scriptblock. Arguments can be accessed by assigning a new variable to the value of the argument and using that. Alternatively you can use the $Args[] syntax directly.

$usergroup = $Args[2] # Third argument

Similar for the other arguments.

You also have setup two of the arguments as parameters, but not the third one. It might work if you added the third parameter ($usergroup) as well. But i would suggest changing your code as follows to make it work. That makes it very visible that the arguments are used as passed into -ArgumentList on Invoke-Command.

$Credential = (Get-Credential -Credential user1)

$PSComputerName = "server1"
$Drive = "e:\"
$DriveLetter = ($Drive -split ":")[0]
$Usergroup = Import-Clixml -Path "I:\9514 - Drift\Powershell Scripts\Project\Oprydning af Shares og AD grupper\CreateFileShare\UserGroup.xml"
$Path = "\\$PSComputerName\($DriveLetter)$\"
$sharename = "User1test" #$textbox1.Text
$users = "user1","user2"

Invoke-Command -ScriptBlock {
    # Assign variables from Arguments
    $Sharename = $Args[0]
    $Drive = $Args[1]
    $Usergroup = $Args[2]

    if (-not (Test-Path -Path ($Drive + $Sharename)))
    {
        New-Item -ItemType directory -Path ($Drive + $Sharename) -ErrorAction 'Stop' | Out-Null
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }
    Else
    {
        $RootACL = Get-Acl -Path ($Drive + $Sharename) -ErrorAction 'Stop'
        $RootACL.SetAccessRuleProtection($false, $true)
    }


    $ACL = New-Object System.Security.AccessControl.FileSystemAccessRule($($usergroup.SamAccountName), "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
    $RootACL.AddAccessRule($ACL)
    Set-Acl -Path $Path$sharename -AclObject $RootACL -ErrorAction 'Stop'
} -ComputerName $PSComputerName -ArgumentList $sharename,$Drive,$Usergroup -Credential:$Credential -ErrorAction 'Stop'

Upvotes: 1

Related Questions