Using variables with invoke-command

Hi all,

Firstly, what a great resource. Thanks to everyone who dedicates their time to helping the powershell community. I am new to powershell and only which that I got on the powershell train 5 years ago when I entered IT.

I am wondering if someone can assist and explain how to use a variable when using invoke-command. Here is a part of a script I am working on:

$data = Import-Csv C:\Scripts\ExchangeServerData.csv
foreach($d in $data){
Invoke-Command -ComputerName $d.MailboxServer -ScriptBlock { 
    Get-Disk | Where-Object {$_.PartitionStyle -eq "Raw"} | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "$($d.ActiveDatabase)-Active" -Confirm:$false
    }
}

The issue I am having is towards the end of that main ‘one-liner’, where I have tried to use -NewFileSystemLabel “$($d.ActiveDatabase)-Active”. The value from my CSV file under ‘ActiveDatabase’ did not get passed through and instead I ended up with a volume that has a label of ‘-Active’.

Can someone shed some light on how to make this work and more importantly (for me), take a few mins to explain it as well. I understand that the variable does not work, because the remote machine does not know about the local variable.

Also, is there a way to use powershell to assign this newly created volume a mount point instead of a drive letter?

Cheers!

The script block that you pass to Invoke-Command runs in a new PowerShell session on the remote computer; it doesn’t automatically inherit the variables in your local scope (such as $d). When that script block runs, $d on the remote server hasn’t been set, so it evaluates to $null.

You can pass variables to a remote script block in two ways: You can use the -ArgumentList parameter to Invoke-Command, or, if both the local and remote computers are running PowerShell 3.0, you can use the “using” variable scope modifier. Personally, I prefer ArgumentList, even when all computers are running the latest version:

$scriptBlock = {
    param ($activeDatabase)
    
    Get-Disk |
    Where-Object {$_.PartitionStyle -eq "Raw"} |
    Initialize-Disk -PartitionStyle MBR -PassThru |
    New-Partition -UseMaximumSize |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "${activeDatabase}-Active" -Confirm:$false
}

$data = Import-Csv C:\Scripts\ExchangeServerData.csv
foreach($d in $data){
    Invoke-Command -ComputerName $d.MailboxServer -ScriptBlock $scriptBlock -ArgumentList $d.ActiveDatabase
}

Awesome thanks so much Dave. I’ll have to do some more reading into arguments with invoke-command.