I am trying to get a shadow storage information from remote computers. I could get the information and store in a variable as table.
But every time the log file is being overwrite by the new information.
My script:
$computerList = Get-Content "C:\Check_ShadowStorage\ServersList.txt"
foreach($computer in $computerList)
{
$a = Invoke-Command -ComputerName $computer -Credential $credential -ScriptBlock {@(vssadmin list shadowstorage | Select-String -Context 0,5 '^Shadow Copy Storage' |
Select @{Label="Shadow Copy Storage"; Expression={$_.Line.Trim("'").SubString(12)}},
@{Label="Volume"; Expression={$_.Context.PostContext[0].Trim().SubString(13,2)}},
@{Label="Used Shadow Copy"; Expression={$_.Context.PostContext[2].Trim().SubString(32)}},
@{Label="Allocated Shadow Copy"; Expression={$_.Context.PostContext[2].Trim().SubString(32)}},
@{Label="Maximum Storage"; Expression={$_.Context.PostContext[4].Trim().SubString(35)}}) |
Format-Table Volume, 'Used Shadow Copy', 'Allocated Shadow Copy', 'Maximum Storage'}
$a | Out-File "C:\Check_ShadowStorage\Output.log"
}
The output I am wishing to have is something like:
Server A
Volume Used Shadow Copy Allocated Shadow Copy Maximum Storage
------ ---------------- --------------------- ---------------
S: 0 bytes (0%) 0 bytes (0%) 89.3 GB (10%)
D: 8.48 GB (0%) 8.48 GB (0%) 93.0 GB (10%)
C: 4.97 GB (8%) 4.97 GB (8%) 5.83 GB (10%)
Server B
Volume Used Shadow Copy Allocated Shadow Copy Maximum Storage
------ ---------------- --------------------- ---------------
S: 0 bytes (0%) 0 bytes (0%) 89.3 GB (10%)
D: 8.48 GB (0%) 8.48 GB (0%) 93.0 GB (10%)
C: 4.97 GB (8%) 4.97 GB (8%) 5.83 GB (10%)
And so on.
The issue with your code is that you're overwriting your output file because:
$a | Out-File "C:\Check_ShadowStorage\Output.log"
Is inside the foreach
instead of outside. To fix it, you could change the foreach
for a ForEach-Object
and use the pipeline:
$computerList | ForEach-Object {
# no assignment to `$a` needed here
Invoke-Command -ComputerName $_ -Credential $credential -ScriptBlock {
# same code here
}
} | Out-File 'C:\Check_ShadowStorage\Output.log'
What you should do instead is not use Format-Table
, output objects from your Invoke-Command
and then pass them to Export-Csv
to have structured output instead of plain text files.
$computerList = Get-Content 'C:\Check_ShadowStorage\ServersList.txt'
Invoke-Command $computerList {
vssadmin list shadowstorage |
Select-String -Context 0, 5 '^Shadow Copy Storage' |
ForEach-Object {
[pscustomobject]@{
'Volume' = $_.Context.PostContext[0].Trim().SubString(13, 2)
'Used Shadow Copy' = $_.Context.PostContext[2].Trim().SubString(32)
'Allocated Shadow Copy' = $_.Context.PostContext[2].Trim().SubString(32)
'Maximum Storage' = $_.Context.PostContext[4].Trim().SubString(35)
'Shadow Copy Storage' = $_.Line.Trim("'").SubString(12)
}
}
} | Select-Object PSComputerName, * -ExcludeProperty RunspaceId |
Export-Csv C:\Check_ShadowStorage\Output.csv -NoTypeInformation