I have a hash containing drive data, the key is the disc number and the values are (in order size, drive letter, and datastore)
$datahash
Name | Value |
---- | ----- |
2 | {3, q, datastore1} |
1 | {4, f, datastore2} |
0 | {40, c, datastore3} |
I'm trying to partition the drives through powercli, but I'm not sure $datahash is actually being pushed to the remote server
$script = @'
$NumDisks = (Get-Wmiobject -class "Win32_DiskDrive").count
for($CurrentDisk = 1; $NumDisks -gt $CurrentDisk; $CurrentDisk++)
{
out-file c:\diskpartscript$currentdisk.txt -Encoding ASCII -InputObject "select disk $CurrentDisk`r`n online disk noerr`r`n attributes disk clear readonly`r`n clean`r`n create partition primary`r`n format fs=ntfs quick`r`n assign letter=$datahash[$currentdisk][1]"
diskpart /s c:\diskpartscript$currentdisk.txt
}
'@
Invoke-VMScript -ScriptText $script -VM $displayname -GuestCredential $localadmincreds -scripttype powershell
When i check c:\diskpartscript$currentdisk.txt at the drive letter section i just see the following:
select disk 1
online disk noerr
attributes disk clear readonly
clean
create partition primary
format fs=ntfs quick
assign letter=[1][1]
Where assign letter should have in this case 'f'
Is $datahash not being pushed to the script block or something?
There are but a few simple rules for variable substitution in here-strings.
As an example
$u = 2
$t1 = @"
Value $u
"@
$t2 = @'
Value $u
'@
$t3 = @"
Value `$u
"@
$t1
$t2
$t3
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Forgot to add I'm calling it with:
Invoke-VMScript -ScriptText $script -VM $displayname -GuestCredential $localadmincreds -scripttype powershell
It's to do with operator priority.
Try as
($datahash[$currentdisk])[1]
What is in the parenthesis will return the array, then you take the 2nd (index 1) element of that array
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It seems like it isnt passing $datahash at all...the output of diskpartscript1.txt has the 'assign letter' field as:
assign letter = ([1])[1]
Am I doing something incorrect with my quotes?
$script = @'
$NumDisks = (Get-Wmiobject -class Win32_DiskDrive).count
for($CurrentDisk = 1; $NumDisks -gt $CurrentDisk; $CurrentDisk++)
{
out-file c:\diskpartscript$currentdisk.txt -Encoding ASCII -InputObject "select disk $CurrentDisk`r`n online disk noerr`r`n attributes disk clear readonly`r`n clean`r`n create partition primary`r`n format fs=ntfs quick`r`n assign letter=($datahash[$currentdisk])[1]"
diskpart /s c:\diskpartscript$currentdisk.txt
}
'@
$hi = "hi"
$script = @'
add-content c:\out.txt $hi
'@
Invoke-VMScript -ScriptText $script -VM $displayname -GuestCredential $localadmincreds -scripttype powershell
This also results in a blank out.txt file....the OS is windows 2012 R2, would that have anything to do with vmscript not being able to pass the $datahash hash?
That is due to the inline string with single quotes (@'...'@).
With single quotes there will be no variable substitution.
Use double quotes
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Using this code:
$script = @" | ||
$NumDisks = (Get-Wmiobject -class Win32_DiskDrive).count | ||
for($CurrentDisk = 1; $NumDisks -gt $CurrentDisk; $CurrentDisk++) | ||
{ | ||
out-file c:\diskpartscript.txt -Encoding ASCII -InputObject "select disk $CurrentDisk`r`n online disk noerr`r`n attributes disk clear readonly`r`n clean`r`n create partition primary`r`n format fs=ntfs quick`r`n assign letter=($datahash[$currentdisk])[1]" | ||
diskpart /s c:\diskpartscript.txt | ||
} | ||
"@ |
Produced the following error:
PowerCLI C:\> Invoke-VMScript -ScriptText $script -vm $displayname -GuestCredential $localadmincreds -ScriptType Powershell
ScriptOutput
-------------------------------------------------------------------------------
At line:2 char:32
| + for( = 1; -gt ; ++)
| + ~
| Missing expression after unary operator '++'.
| + CategoryInfo : ParserError: (:) [],
ParentContainsErrorRecordEx
| ception
| + FullyQualifiedErrorId : MissingExpressionAfterOperator
|
|
-------------------------------------------------------------------------------
The below code works, I had to hardcode the variable names in, if you have a better method please let me know!
$i = 1
do
{
$drive = $datahash.Keys | ? {$_ -eq $i} | %{$datahash[$_][1]}
$script = @"
out-file c:\diskpartscript.txt -Encoding ASCII -InputObject "select disk $i`r`n online disk noerr`r`n attributes disk clear readonly`r`n clean`r`n create partition primary`r`n format fs=ntfs quick`r`n assign letter=$drive"
diskpart /s c:\diskpartscript.txt
"@
Invoke-VMScript -ScriptText $script -VM $displayname -GuestCredential $localadmincreds -scripttype powershell
$i++
}
until($i -eq $datahash.count)
After some further editing, i got it down to:
foreach ( $name in $datahash.keys )
{
$script += '"select disk ' + $name + '`r`nonline disk noerr`r`nattributes disk clear readonly`r`nclean`r`ncreate partition primary`r`nformat fs=ntfs quick`r`nassign letter=' + $datahash[$name][1] + '"|diskpart;'
}
Invoke-VMScript -ScriptText $script -VM $displayname -GuestCredential $localadmincreds -scripttype powershell | out-null
There are but a few simple rules for variable substitution in here-strings.
As an example
$u = 2
$t1 = @"
Value $u
"@
$t2 = @'
Value $u
'@
$t3 = @"
Value `$u
"@
$t1
$t2
$t3
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Very helpful post for the future, thanks!