Comparing array variables in PowerShell

风格不统一 提交于 2019-12-17 07:30:20

问题


I have this script to compare two folders.

$firstfolder = Get-ChildItem C:\firstfolder
$secondfolder = Get-ChildItem C:\firstfolder

if ($firstfolder -eq $secondfolder) {
Write-Host "Folders are the same."
} else {
    Write-Host "Error: Doesn't match."
}

As you can see, I compare the same folder. Problem is, that it will never consider, that the arrays are equal. Why?


回答1:


In PowerShell, variables that point to arrays are evaluated in expressions by enumerating the contents of the arrays themselves.

For example this expression:

$firstFolder | Get-Member

will return information about the System.IO.DirectoryInfo type, which indeed is the type of the first element in the $firstFolder array. If you want to operate on the array object itself, you have to explicitly tell PowerShell to treat the object as array by using the , operator. The following expression:

,$firstFolder | Get-Member

will expectedly return information about System.Object[].

However, when the -eq operator is used between two array variables, things are a bit different. PowerShell will, in fact, enumerate only the array on the left side and compare each item to the array on the right side as a whole. The result will be an array of matching items or nothing at all when there are no matches. For example:

$a = 1..5
$b = 1..5
$a -eq $b         # returns zero-length array
[bool]($a -eq $b) # returns $false
$a -eq 3          # returns 3

In your particular case, the result will be zero-length array (or $false if casted to a boolean) since the $firstFolder array contains System.IO.DirectoryInfo objects that don't quite match the array in the $secondFolder variable.

What you really want is to compare the contents of both arrays against each other. This is where the Compare-Object cmdlet comes in handy:

Compare-Object $firstFolder $secondFolder -SyncWindow 0

This will return an array of differences between the two arrays or $null when the arrays are equal. More precisely, the resulting array will contain an object for each item that exists only in one array and not the other. The -SyncWindow 0 argument will make the order in which the items appear in the arrays count as a difference.

If all you need is a simple way to tell whether the two arrays are different without going into the details of what is different, you can simply check the length of the array returned by Compare-Object:

$areEqual = @(Compare-Object $firstFolder $secondFolder -SyncWindow 0).Length -eq 0

Notice how I explicitly told PowerShell to always package the results into an array, since Compare-Object may return $null when the arrays don't contain any differences.




回答2:


For this kind of comparisons you have to use cmdlet compare-object and evaluate if there's differences or not!




回答3:


Maybe something like this.

function arrayequal($a, $b) {
  -not (compare $a $b)
}

arrayequal $a $b

True


来源:https://stackoverflow.com/questions/9598173/comparing-array-variables-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!