SCRT-HQ / PSGSuite

Powershell module for Google / G Suite API calls wrapped in handy functions. Authentication is established using a service account via P12 key to negate the consent popup and allow for greater handsoff automation capabilities
https://psgsuite.io/
Apache License 2.0
235 stars 67 forks source link

Piping array to Get-GSUserLicense repeatedly returning first item #212

Closed reedwilemon closed 5 years ago

reedwilemon commented 5 years ago

Describe the bug Piping array to Get-GSUserLicense repeatedly returning results of first item from array

To Reproduce Steps to reproduce the behavior:

  1. $users = Get-GSUser -Filter * -SearchBase / -SearchScope Base
  2. $users | Get-GSUserLicense

Expected behavior Get-GSUserLicense should return license information for each item in array

Screenshots Using Get-Unique to avoid displaying data. image

Environment (please complete the following information):

Additional context Same result when using $users.user

scrthq commented 5 years ago

Thanks for opening this up @reedwilemon ! I'm replicating it on my end. Doing some testing now around a fix.

scrthq commented 5 years ago

@reedwilemon - 2 things going on here:

  1. There is a indeed bug that is now fixed and will be deployed soon. The issue there is that $response was being set with the first user that had a license matched, resulting in the other users in the pipeline immediately returning nothing since $response was no longer empty. If you run the Get-GSUserLicense section with -Verbose on, you can see that returning immediately after the first license type is checked for users 2-n.
  2. Even with the fix, Get-Unique is a bad way to measure those license objects as it appears to be casting the incoming objects ToString(), which for most objects that PSGSuite returns simply results in the type name being returned due to default behavior in .NET. User objects returned from Get-GSUser explicitly do not have this problem as I'm explicitly overriding the ToString() method on the resulting objects to return the PrimaryEmail, which will result in that being unique when piped into Get-Unique. A better way to measure is to use another Cmdlet that does support a -Unique switch like Select-Object UserId -Unique or Sort-Object UserId -Unique, then checking the Count of the resulting output. You can still pass to Get-Unique if you'd like (the documentation for Get-Unique demonstrates piping the output of Get-Process to Select-Object, for example), but you're adding more to the pipeline to achieve the same result in my opinion.

Some quick examples:

Current PSGSuite (2.30.1)

$users = Get-GSUser -Filter * -SearchBase / -SearchScope Base
$licenses = $users | Get-GSUserLicense -Verbose 
# ^^^ Notice how the results after the first return immediately after the first license type check in the array?

# Should be more than 1
$users.Count

# Will be 1 because the subsequent items in the pipeline don't return anything due to this issue, even though we're passing it an array of what would be unique strings if Get-GSUserLicense was working correctly
($licenses.UserId | Get-Unique).Count

# Will be 1 because it's comparing the resulting object when cast ToString(),
#  which returns the object type by default: Google.Apis.Licensing.v1.Data.LicenseAssignment
($licenses | Get-Unique).Count

With fix (v2.30.2 - coming shortly)

$users = Get-GSUser -Filter * -SearchBase / -SearchScope Base
$licenses = $users | Get-GSUserLicense -Verbose 
# ^^^ Notice how the results after the first return immediately after the first license type check in the array?

# Should be more than 1
$users.Count

# Will match the result of $users.Count, assuming that all users piped into Get-GSUserLicense actually have a license assigned to them
($licenses.UserId | Get-Unique).Count
# This also works the same:
$licenses | Select-Object -ExpandProperty UserId | Get-Unique | Measure-Object

# Will still be unexpectedly 1 because it's comparing the resulting object when cast ToString(), which returns the object type by default: Google.Apis.Licensing.v1.Data.LicenseAssignment
# Make sure you pair down to exactly what you want if you're going to continue using Get-Unique so this doesn't impact you later
($licenses | Get-Unique).Count

Current (red showing the actual issue that's now fixed): image

After fix (red showing false issue due to oddities with Get-Unique, with green showing it working when you only provide it a list of strings to process): image

scrthq commented 5 years ago

@reedwilemon - Fix deployed in 2.30.2! Let me know if you're having issues still and keep that Get-Unique gotcha in mind! Cheers!