0

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.

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. Doesn't seem to work in my example code, but it may work where I actually need it, so will let you know tomorrow when I'm back at work. +1 in the meanwhile. :) EDIT never mind it works, but I had licensecounting, you have licensecount
And now also got it to work in my code at work. Needed a few tweaks but that was just because I had it wrong in the first place. Thanks again. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.