Hello,
I’ve got a CSV file that I use for different tasks associated with managing Windows Image files. I’m trying to use a ForEach-Object
along with an If/Else
statement that can find a new item in the list of src_names
in the CSV file, and when it finds it, to take action on it. Easier said than done I realize.
However, after running my script, it added all of the images in the CSV list to the WIM file. I then realized that I need a way to compare the two sources first. The Compare-Object
looks promising, but I’m having trouble slimming it down so to speak.
I looked at the following posts for some insight:
- Splitting a csv by comparing values against arrays - PowerShell Help - PowerShell Forums
- Compare two arrays and only get objects that are not part of the other one - PowerShell Help - PowerShell Forums
My first attempt:
Import-Csv "C:\Mounts\WindowsRepairSource\List-SourceNames.csv" | ForEach {
if($($_.src_name) -eq $true){
Write-Host "Source Name exists"
}else{
Export-WindowsImage -SourceImagePath "$($_.osd_media)`\$($_.osd_name)`\$($_.osd_sources)`\install.wim" -SourceName "$($_.src_name)" -DestinationImagePath "$($_.wrs_local)`\$($_.wrs_wim)" -CheckIntegrity -CompressionType "max"
}
}
I’m using the object format $($_.src_name)
versus a standard variable $src_name because of the ForEach-Object
to read the contents of the CSV file.
Basically, I was importing the CSV file, then piping it into a ForEach
loop, and then using an If/Else
to determine what action to take. I was expecting it to look down the src_name
column in the CSV file and see what is new. However, that’s when I realized I wasn’t comparing that list to the contents of the WIM file.
My attempts at comparing:
$wrs_local = "C:\Mounts\WindowsRepairSource"
$csv_names = Import-Csv "$wrs_local\List-SourceNames.csv" | Select @{l='src_name';e={$_.src_name}} # Example from StackOverflow.com
$wim_array = Get-WindowsImage -ImagePath "$wrs_local\RepairSource.wim" | Select-Object ImageName
These two gave me undesired results:
Compare-Object -ReferenceObject $csv_names -DifferenceObject $wim_array -Property src_name -IncludeEqual
Compare-Object -ReferenceObject $csv_names -DifferenceObject $wim_array -Property src_name -PassThru
Trying to create an array for the items that are new (different):
$add_array = Compare-Object $csv_names $wim_array | Where-Object { $_.SideIndicator -eq '<=' } | Foreach-Object { $_.InputObject }
Output:
src_name SideIndicator
-------- -------------
Windows Server 2022 Datacenter <=
My attempt at sliming it down to just the name of the operating system (src_name) in my CSV file which I’m calling a $csv_array
:
$add_array = Compare-Object $csv_names $wim_array | Where-Object { $_.SideIndicator -ne $_.src_name } | Foreach-Object { $_.InputObject } | Select-Object $add_array.src_name
Output:
Windows Server 2022 Datacenter
------------------------------
This is the best I could get for now. Trying to get just the src_name
(Windows Server 2022 Datacenter)
I even tried Microsoft’s Example #2 in their Help page for Compare-Object
:
# Example 2 - Compare each line of content and exclude the differences
$objects = @{
$csv_names = Import-Csv "$wrs_local\List-SourceNames.csv" | Select @{l='src_name';e={$_.src_name}}
$wim_array = Get-WindowsImage -ImagePath "$wrs_local\RepairSource.wim" | Select-Object ImageName
}
Compare-Object @objects -IncludeEqual -ExcludeDifferent
Unfortunately, that was a dead end; not to mention that excludes the differences and my objective was to capture the differences.
I was hoping to build a new array with just the OS names that I can use to take action on within the If/Else
statement above; or possibly a Switch
statement.
- If
src_name
in CSV exists in the wim file, skip to the next row. - Else, run this command.
Any insight would be greatly appreciated. Thank you.