Reputation: 884
I query users in Office365 and need to count how many licenses they have based on what domain their UserPrincipalName has. In order to make it easier to troubleshoot, I've created a new script that focuses solely on the problem, but I can't get it to work even there.
Here's my script:
#$users = get-msoluser -TenantId $customer.TenantId -All | Where-Object {$_.islicensed} | Sort-Object UserPrincipalName
$users = @(
[pscustomobject]@{
name='User1'
domain='domain1'
license='A'
}
[pscustomobject]@{
name='User2'
domain='domain2'
license='A', 'B'
}
[pscustomobject]@{
name='User3'
domain='domain1'
license='A', 'B'
}
[pscustomobject]@{
name='User4'
domain='domain1'
license='B'
}
[pscustomobject]@{
name='User5'
domain='domain2'
license='A'
}
[pscustomobject]@{
name='User6'
domain='domain1'
license='B'
}
[pscustomobject]@{
name='User7'
domain='domain1'
license='A','B'
}
)
$domains = 'domain1','domain2'
$users |fl *
$domains |fl
$LicenseCounting = @{}
$domains | foreach-object {
$LicenseCounting[$_] = @{}
}
foreach($user in $users)
{
$licenses = @()
$user.license | foreach-object {
$licenses += $_
}
$LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains][$licenses] + 1
}
$LicenseCounting | fl *
<# expected result:
$licenseCounting[domain1][A]=3
$licenseCounting[domain1][B]=4
$licenseCounting[domain2][A]=2
$licenseCounting[domain2][B]=1
#>
output:
name : User1
domain : domain1
license : A
name : User2
domain : domain2
license : {A, B}
name : User3
domain : domain1
license : {A, B}
name : User4
domain : domain1
license : B
name : User5
domain : domain2
license : A
name : User6
domain : domain1
license : B
name : User7
domain : domain1
license : {A, B}
domain1
domain2
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"
.
At C:\Users\xxxxxxx\Documents\array count test.ps1:58 char:5
+ $LicenseCounting[$domains][$licenses] = $LicenseCounting[$domains ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Name : domain2
Key : domain2
Value : {}
Name : domain1
Key : domain1
Value : {}
In my example, I'm getting an error. When I use the first row that is commented out, it actually does work, but instead of counting, it puts all licenses in a string: eg, 'A', 'A', 'B', 'A'... etc. I'm sure once I get it to work in my example, I can get it to work in the real case too.
Upvotes: 0
Views: 163
Reputation: 174545
You need to reference specific domain and license identifier values when assigning to your hashtable:
$licenseCount = @{}
foreach($user in $users){
# Create top-level per-domain hashtable for $user.domain if it doesn't already exist
if(-not $licenseCount.ContainsKey($user.domain)){
$licenseCount[$user.domain] = @{}
}
$user.license |ForEach-Object {
# Count each license type separately, store in previously created per-domain hashtable
$licenseCount[$user.domain][$_] += 1
}
}
$licenseCount
will now have been populated with the information as described in your post:
PS ~> $licenseCount['domain2']['A']
2
Upvotes: 2