DisplayGroupInfo.ps1
$RefreshErrors_Click = { out-logfile -string "Refreshing user license errors selected." $errorsView.columns.clear() GetGroupErrors DrawDataGrid -initialLoad $false } $ReprocessUsers_Click = { out-logfile -string "Reprocessing user licenses selected." $checkedRows = $errorsView.rows | where {$_.cells["CheckboxColumn"].value -eq $true} out-logfile -string ("Number of users for reprocessing: "+$checkedRows.count) if ($checkedRows.count -gt 0) { $successCount = 0 $errorCount = 0 out-logfile -string "There are users for reprocessing." foreach ($row in $checkedRows) { out-logfile -string ("Reprocessing user: "+$row.cells["ID"].value) try { Invoke-MGLicenseUser -userID $row.cells["ID"].value -errorAction STOP out-logfile -string "User reprocessed successfully." $successCount++ } catch { out-logfile -string $_ out-logfile -string ("Unable to process a license reprocessing: "+$row.cells["ID"].value) $errorText = CalculateError $_ [System.Windows.Forms.MessageBox]::Show("Unable to reprocess: "+$row.cells["ID"].value+" Error: "+$errorText, 'Warning') $errorCount++ } } if ($errorCount -eq 0) { [System.Windows.Forms.MessageBox]::Show("All users reprocessed successfully. View Entra audit logs for details or refresh error view.", 'Info') } } else { out-logfile -string "No users for reprocessing." } } $GroupInfo_Load = { if ($global:allowReprocessing -eq $TRUE) { $RefreshErrors.show() $ReprocessUsers.show() } DrawDataGrid } $CloseDisplay_Click = { $GroupInfo.close() } function DrawDataGrid { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] $initialLoad = $true ) if ($initialLoad -eq $TRUE) { out-logfile -string "Setting up the members columns.." $membersView.columnCount = 4 $membersViewColumns = @() $membersViewColumns = @("ID","DisplayName","UserPrincipalName","ObjectType") foreach ($entry in $membersViewColumns ) { out-logfile -string $entry } out-logfile -string "Adding member columns to table..." for ($i = 0 ; $i -lt $membersViewColumns.count ; $i++) { $membersView.columns[$i].name = $membersViewColumns[$i] $membersView.Columns[$i].ReadOnly = "true" } out-logfile -string "Adding all members information to the table..." foreach ($member in $global:graphMembersArray) { $membersView.rows.add($member.ID,$member.DisplayName,$member.UserPrincipalName,$member.ObjectType) } $membersView.Columns | Foreach-Object{ $_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells } } out-logfile -string "Setting up errors columns..." #$errorsView.columnCount = 5 $errorsViewColumns = @() $errorsViewColumns = @("ID","DisplayName","UserPrincipalName","Error","ObjectType") foreach ($entry in $errorsViewColumns ) { out-logfile -string $entry } out-logfile -string "Creating checkbox column..." $checkboxColumn = New-Object System.Windows.Forms.DataGridViewCheckBoxColumn $checkboxColumn.HeaderText = "Select User" $checkboxColumn.Name = "CheckboxColumn" $errorsView.columns.add($checkboxColumn) out-logfile -string "Adding additional columns to the table..." for ($i = 0 ; $i -lt $errorsViewColumns.count ; $i++) { #$errorsView.columns[$i].name = $errorsViewColumns[$i] $errorsView.columns.add($errorsViewColumns[$i],$errorsViewColumns[$i]) } for ($i = 1 ; $i -lt $errorsViewColumns.count ; $i++) { $errorsView.Columns[$i].ReadOnly = "true" } $wrapCellStyle = New-Object System.Windows.Forms.DataGridViewCellStyle $wrapCellStyle.WrapMode = [System.Windows.Forms.DataGridViewTriState]::True $errorsView.columns[4].defaultCellStyle = $wrapCellStyle out-logfile -string "Adding error information to the table..." foreach ($member in $global:graphMembersErrorArray) { $errorsView.rows.add($false,$member.ID,$member.DisplayName,$member.UserPrincipalName,$member.error,$member.ObjectType) } $errorsView.Columns | Foreach-Object{ $_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells } $errorsView.autosizerowsmode = "AllCells" if ($initialLoad -eq $TRUE) { if ($global:graphMembersArray.count -gt 0) { $groupCountBox.appendtext($global:graphMembersArray.count.tostring()) } else { $groupCountBox.appendtext("0") } } if ($global:graphMembersErrorArray.count -gt 0) { $errorCountBox.clear() $errorCountBox.appendtext($global:graphMembersErrorArray.count.tostring()) } else { $errorCountBox.clear() $errorCountBox.appendtext("0") } $LicenseTextBox.clear() $LicenseTextBox.appendText($global:graphGroup.LicenseProcessingState.State) } function GetGroupErrors { $global:graphMembersErrorArray = @() $operationSuccessful = $false out-logfile -string "Determine if any group license errors exist." try { $global:graphErrorGroupMembers = Get-MgGroupMemberWithLicenseError -GroupId $global:graphGroup.id -all -errorAction Stop $operationSuccessful = $true } catch { $errorText = $_ out-logfile -string "Unable to obtain the members in error..." out-logfile -string $_ [System.Windows.Forms.MessageBox]::Show("Unable to obtain the members in error..."+$errorText, 'Warning') $global:ErrorMessages += $errorText } $global:graphErrorGroupMembers = $global:graphErrorGroupMembers | Sort-Object -Property ID -Unique out-logfile -string "Parse the error members to obtain the error reason." if ($operationSuccessful -eq $TRUE) { if ($global:graphErrorGroupMembers.count -gt 0) { out-logfile -string "The group has users in error - process each user." foreach ($member in $global:graphErrorGroupMembers) { $functionUser = get-MGUser -userID $member.id -Property ID,DisplayName,assignedLicenses,licenseAssignmentStates | Select-Object -ExpandProperty LicenseAssignmentStates $functionUser = $functionUser | where {$_.AssignedByGroup -eq $global:graphGroup.Id} if ($functionUser.count -gt 0) { $functionError = @() out-logfile -string "The error count is gt 0" foreach ($errorString in $functionUser) { $commonName = $global:skuGuidHash[$errorString.SkuID].'???Product_Display_Name' $functionString = $errorString.error +"---"+ $commonName + "---" + $errorString.State $functionError += $functionString } $functionError = $functionError -join "`r`n" } else { $functionString = $functionUser.error +"," + $functionUser.SkuID + "," + $functionUser.State $functionError = $functionString } <# $functionError = $functionUser.Error if ($functionError.count -gt 0) { out-logfile -string "There are more than one errors." $functionError = $functionError -join "," } else { out-logfile -string "Single error leave it alone." } #> out-logfile -string ("The user error type is:") out-logfile -string $functionError out-logfile -string $member.AdditionalProperties.'@odata.type' if ($member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.user") { $functionObjectType = "User" $functionUPN = $member.AdditionalProperties.userPrincipalName } elseif($member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.group") { $functionObjectType = "Group" $functionUPN = "N/A" } elseif($member.AdditionalProperties.'@odata.context' -eq "https://graph.microsoft.com/v1.0/$metadata#contacts/$entity") { $functionObjectType = "Contact" $functionUPN = "N/A" } $functionObject = New-Object PSObject -Property @{ ID = $member.Id DisplayName = $member.AdditionalProperties.displayName UserPrincipalName = $functionUPN Error = $functionError ObjectType = $functionObjectType } $global:graphMembersErrorArray += $functionObject } out-logfile -string ("Count of error objects: "+$global:graphMembersErrorArray.count) } } } function DisplayGroupInfo { $global:graphMembersErrorArray = @() $global:graphMembersArray = @() out-logfile -string "Obtaining group membership..." $operationSuccessful = $FALSE try { $graphGroupMembers = Get-MgGroupMember -GroupId $global:graphGroup.id -all -errorAction Stop $operationSuccessful = $TRUE } catch { $errorText = $_ out-logfile -string "Unable to obtain graph group membership..." out-logfile -string $_ [System.Windows.Forms.MessageBox]::Show("Unable to obtain graph group membership..."+$errorText, 'Warning') $global:ErrorMessages += $errorText } out-logfile -string "Parse all members for information to add to the table." if ($operationSuccessful -eq $TRUE) { foreach ($member in $graphGroupMembers) { if ($member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.user") { $functionObjectType = "User" $functionUPN = $member.AdditionalProperties.userPrincipalName } elseif($member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.group") { $functionObjectType = "Group" $functionUPN = "N/A" } elseif($member.AdditionalProperties.'@odata.context' -eq "https://graph.microsoft.com/v1.0/$metadata#contacts/$entity") { $functionObjectType = "Contact" $functionUPN = "N/A" } $functionObject = New-Object PSObject -Property @{ ID = $member.Id DisplayName = $member.AdditionalProperties.displayName UserPrincipalName = $functionUPN ObjectType = $functionObjectType } $global:graphMembersArray += $functionObject } } if ($operationSuccessful -eq $TRUE) { GetGroupErrors } Add-Type -AssemblyName System.Windows.Forms . (Join-Path $PSScriptRoot 'displaygroupinfo.designer.ps1') $GroupInfo.ShowDialog() } |