From c2c147c809550e14f687eaa271eb092cc8edc147 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 12:35:40 +1000 Subject: [PATCH 01/10] Update Copyright to 2024 --- src/MSIdentityTools.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSIdentityTools.psd1 b/src/MSIdentityTools.psd1 index 5ba9b25..c0e5a7c 100644 --- a/src/MSIdentityTools.psd1 +++ b/src/MSIdentityTools.psd1 @@ -25,7 +25,7 @@ CompanyName = 'Microsoft Corporation' # Copyright statement for this module - Copyright = '(c) 2023 Microsoft Corporation. All rights reserved.' + Copyright = '(c) 2024 Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module Description = 'Tools for managing, troubleshooting, and reporting on various aspects of Microsoft Identity products and services, primarily Microsoft Entra ID.' From 987dd657176748c24d584250a3b9bbdbace8e4c6 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 12:37:55 +1000 Subject: [PATCH 02/10] Update Remove-MsIDUserAuthMethod To align with style --- src/MSIdentityTools.psd1 | 4 ++-- src/Remove-MsidUserAuthenticationMethod.ps1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MSIdentityTools.psd1 b/src/MSIdentityTools.psd1 index c0e5a7c..c0dd2bb 100644 --- a/src/MSIdentityTools.psd1 +++ b/src/MSIdentityTools.psd1 @@ -131,7 +131,7 @@ '.\New-MsIdSamlRequest.ps1' '.\New-MsIdTemporaryUserPassword.ps1' '.\New-MsIdWsTrustRequest.ps1' - '.\Remove-MsidUserAuthenticationMethod.ps1' + '.\Remove-MsIdUserAuthenticationMethod.ps1' '.\Reset-MsIdExternalUser.ps1' '.\Resolve-MsIdAzureIpAddress.ps1' '.\Revoke-MsIdServicePrincipalConsent.ps1' @@ -191,7 +191,7 @@ 'New-MsIdClientSecret' 'New-MsIdSamlRequest' 'New-MsIdTemporaryUserPassword' - 'Remove-MsidUserAuthenticationMethod' + 'Remove-MsIdUserAuthenticationMethod' 'Reset-MsIdExternalUser' 'Resolve-MsIdTenant' 'Revoke-MsIdServicePrincipalConsent' diff --git a/src/Remove-MsidUserAuthenticationMethod.ps1 b/src/Remove-MsidUserAuthenticationMethod.ps1 index 7923df6..61446b9 100644 --- a/src/Remove-MsidUserAuthenticationMethod.ps1 +++ b/src/Remove-MsidUserAuthenticationMethod.ps1 @@ -12,10 +12,10 @@ .EXAMPLE Connect-MgGraph -Scopes UserAuthenticationMethod.ReadWrite.All - Remove-MsidUserAuthenticationMethod -UserId john@contoso.com + Remove-MsIdUserAuthenticationMethod -UserId john@contoso.com #> -function Remove-MsidUserAuthenticationMethod { +function Remove-MsIdUserAuthenticationMethod { [CmdletBinding(HelpUri = 'https://azuread.github.io/MSIdentityTools/commands/Remove-MsidUserAuthenticationMethod')] param ( # The user UPN or ID to delete the authentication methods for. From 25fe979663eea4de40f8ed861b86bc958f701213 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 12:41:43 +1000 Subject: [PATCH 03/10] Update Example in Remove-MsIdUserAuth to align with Pester test --- src/Remove-MsidUserAuthenticationMethod.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Remove-MsidUserAuthenticationMethod.ps1 b/src/Remove-MsidUserAuthenticationMethod.ps1 index 61446b9..0468cbc 100644 --- a/src/Remove-MsidUserAuthenticationMethod.ps1 +++ b/src/Remove-MsidUserAuthenticationMethod.ps1 @@ -11,9 +11,9 @@ .EXAMPLE Connect-MgGraph -Scopes UserAuthenticationMethod.ReadWrite.All - Remove-MsIdUserAuthenticationMethod -UserId john@contoso.com - + + This example deletes all the authentication methods for the user #> function Remove-MsIdUserAuthenticationMethod { [CmdletBinding(HelpUri = 'https://azuread.github.io/MSIdentityTools/commands/Remove-MsidUserAuthenticationMethod')] From f8429ad230c90894e73c27f88b032c6bf2b78465 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 12:44:32 +1000 Subject: [PATCH 04/10] Description added to Test-MsIDCBATrustStoreCon Example --- src/Test-MsIdCBATrustStoreConfiguration.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Test-MsIdCBATrustStoreConfiguration.ps1 b/src/Test-MsIdCBATrustStoreConfiguration.ps1 index 14ebac6..94d6398 100644 --- a/src/Test-MsIdCBATrustStoreConfiguration.ps1 +++ b/src/Test-MsIdCBATrustStoreConfiguration.ps1 @@ -24,6 +24,8 @@ .EXAMPLE Test-MsIdCBATrustStoreConfiguration + + Run tests against the current tenant's Certificate Trust Store .LINK https://aka.ms/aadcba From 2a747198afaf7c57c51e5f835bda1a7e625ce584 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 13:00:49 +1000 Subject: [PATCH 05/10] Add Depenency checker on two critial commands used in Export-MsIdAppConGrantReport --- src/Export-MsIdAppConsentGrantReport.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Export-MsIdAppConsentGrantReport.ps1 b/src/Export-MsIdAppConsentGrantReport.ps1 index 4197619..1a2e553 100644 --- a/src/Export-MsIdAppConsentGrantReport.ps1 +++ b/src/Export-MsIdAppConsentGrantReport.ps1 @@ -54,6 +54,14 @@ function Export-MsIdAppConsentGrantReport { $ThrottleLimit = 20 ) + begin{ + ## Initialize Critical Dependencies + $CriticalError = $null + if (!(Test-MgCommandPrerequisites 'Get-MgServicePrincipal', 'Get-MgDirectoryObjectById' -ErrorVariable CriticalError)) { return } + } + + process{ + if ($CriticalError) { return } $script:ObjectByObjectId = @{} # Cache for all directory objects $script:KnownMSTenantIds = @("f8cdef31-a31e-4b4a-93e4-5f571e91255a", "72f988bf-86f1-41af-91ab-2d7cd011db47") @@ -613,4 +621,5 @@ function Export-MsIdAppConsentGrantReport { # Call main function Main + } } From e6a6b73f694cac61f74eed2e18e09ca1ad43b3b4 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 13:06:11 +1000 Subject: [PATCH 06/10] Moved Excelworkbook and connect-mgGraph Check into the begin block --- src/Export-MsIdAppConsentGrantReport.ps1 | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Export-MsIdAppConsentGrantReport.ps1 b/src/Export-MsIdAppConsentGrantReport.ps1 index 1a2e553..098b6ac 100644 --- a/src/Export-MsIdAppConsentGrantReport.ps1 +++ b/src/Export-MsIdAppConsentGrantReport.ps1 @@ -56,16 +56,6 @@ function Export-MsIdAppConsentGrantReport { begin{ ## Initialize Critical Dependencies - $CriticalError = $null - if (!(Test-MgCommandPrerequisites 'Get-MgServicePrincipal', 'Get-MgDirectoryObjectById' -ErrorVariable CriticalError)) { return } - } - - process{ - if ($CriticalError) { return } - $script:ObjectByObjectId = @{} # Cache for all directory objects - $script:KnownMSTenantIds = @("f8cdef31-a31e-4b4a-93e4-5f571e91255a", "72f988bf-86f1-41af-91ab-2d7cd011db47") - - function Main() { if ("ExcelWorkbook" -eq $ReportOutputType) { # Determine if the ImportExcel module is installed since the parameter was included if ($null -eq (Get-Module -Name ImportExcel -ListAvailable)) { @@ -77,6 +67,16 @@ function Export-MsIdAppConsentGrantReport { Connect-MgGraph -Scopes Directory.Read.All } + $CriticalError = $null + if (!(Test-MgCommandPrerequisites 'Get-MgServicePrincipal', 'Get-MgDirectoryObjectById' -ErrorVariable CriticalError)) { return } + } + + process{ + if ($CriticalError) { return } + $script:ObjectByObjectId = @{} # Cache for all directory objects + $script:KnownMSTenantIds = @("f8cdef31-a31e-4b4a-93e4-5f571e91255a", "72f988bf-86f1-41af-91ab-2d7cd011db47") + + function Main() { $appConsents = GetAppConsentGrants if ($null -ne $appConsents) { @@ -623,3 +623,4 @@ function Export-MsIdAppConsentGrantReport { Main } } +Export-MsIdAppConsentGrantReport -ExcelWorkbookPath .\report.xlsx From bf9f75bac9be97967ef077c8dea159de0a386e93 Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 14:11:20 +1000 Subject: [PATCH 07/10] Fixed issue where only commands that had multiple results would work. --- src/Export-MsIdAppConsentGrantReport.ps1 | 2 +- src/internal/Test-MgCommandPrerequisites.ps1 | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Export-MsIdAppConsentGrantReport.ps1 b/src/Export-MsIdAppConsentGrantReport.ps1 index 098b6ac..7ff02ec 100644 --- a/src/Export-MsIdAppConsentGrantReport.ps1 +++ b/src/Export-MsIdAppConsentGrantReport.ps1 @@ -623,4 +623,4 @@ function Export-MsIdAppConsentGrantReport { Main } } -Export-MsIdAppConsentGrantReport -ExcelWorkbookPath .\report.xlsx +#Export-MsIdAppConsentGrantReport -ExcelWorkbookPath .\report.xlsx diff --git a/src/internal/Test-MgCommandPrerequisites.ps1 b/src/internal/Test-MgCommandPrerequisites.ps1 index 341518d..7826193 100644 --- a/src/internal/Test-MgCommandPrerequisites.ps1 +++ b/src/internal/Test-MgCommandPrerequisites.ps1 @@ -45,10 +45,13 @@ function Test-MgCommandPrerequisites { ## Get Graph Command Details [hashtable] $MgCommandLookup = @{} foreach ($CommandName in $Name) { - [array] $MgCommands = Find-MgGraphCommand -Command $CommandName -ApiVersion $ApiVersion - - if ($MgCommands.Count -gt 1) { + [array] $MgCommands = Find-MgGraphCommand -Command $CommandName -ApiVersion $ApiVersion -ErrorAction Break + + if ($MgCommands.Count -eq 1) { + $MgCommand = $MgCommands[0] + } + elseif ($MgCommands.Count -gt 1) { $MgCommand = $MgCommands[0] ## Resolve from multiple results [array] $MgCommandsWithPermissions = $MgCommands | Where-Object Permissions -NE $null @@ -65,7 +68,12 @@ function Test-MgCommandPrerequisites { } } - $MgCommandLookup[$MgCommand.Command] = $MgCommand + if ($MgCommand) { + $MgCommandLookup[$MgCommand.Command] = $MgCommand + } + else { + Write-Error "Unable to resolve a specific command for '$CommandName'." + } } ## Import Required Modules From 8aa12524764e3fc710b1e98977d8b61ba638ca3a Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 15:02:54 +1000 Subject: [PATCH 08/10] Updated Test to check for Single Command Returned from Find-MgGraphCommand --- tests/Test-MgCommandPrerequisites.tests.ps1 | 44 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/tests/Test-MgCommandPrerequisites.tests.ps1 b/tests/Test-MgCommandPrerequisites.tests.ps1 index ee1f418..c41d86d 100644 --- a/tests/Test-MgCommandPrerequisites.tests.ps1 +++ b/tests/Test-MgCommandPrerequisites.tests.ps1 @@ -66,8 +66,8 @@ Describe 'Test-MgCommandPrerequisites' { Context 'Name: ' -ForEach @( @{ Name = 'Get-MgUser'; Expected = $true } - @{ Name = 'Get-MgUser'; ApiVersion = 'Beta'; Expected = $true } - @{ Name = 'Get-MgUser'; ApiVersion = 'Beta'; MinimumVersion = '1.0'; Expected = $true } + @{ Name = 'Get-MgUser'; ApiVersion = 'V1.0'; Expected = $true } + @{ Name = 'Get-MgUser'; ApiVersion = 'V1.0'; MinimumVersion = '1.0'; Expected = $true } ) { BeforeAll { InModuleScope $PSModule.Name -ArgumentList $_ { @@ -102,6 +102,46 @@ Describe 'Test-MgCommandPrerequisites' { } } + Context 'Find-MgGraphCommand: Returns Single Command' { + BeforeAll { + Mock -ModuleName $PSModule.Name Find-MgGraphCommand { + New-Object Microsoft.Graph.PowerShell.Authentication.Models.GraphCommand -Property @{ + Command = 'Get-MgDirectoryObjectById' + Module = 'Users' + APIVersion = 'v1.0' + Method = 'POST' + URI = '/directoryObjects/getByIds' + Permissions = @( + ) + } + } -ParameterFilter { $Command -eq 'Get-MgUser' } -Verifiable + } + + It 'Positional Parameter' { + InModuleScope $PSModule.Name -ArgumentList $TestCases[0] { + $Output = Test-MgCommandPrerequisites 'Get-MgUser' -ErrorVariable actualErrors + $Output | Should -BeOfType [bool] + $Output | Should -BeExactly $true + Should -Invoke Find-MgGraphCommand -ParameterFilter { + $Command -eq 'Get-MgUser' + } + $actualErrors | Should -HaveCount 0 + } + } + + It 'Pipeline Input' { + InModuleScope $PSModule.Name -ArgumentList $TestCases[0] { + $Output = 'Get-MgUser' | Test-MgCommandPrerequisites -ErrorVariable actualErrors + $Output | Should -BeOfType [bool] + $Output | Should -BeExactly $true + Should -Invoke Find-MgGraphCommand -ParameterFilter { + $Command -eq 'Get-MgUser' + } + $actualErrors | Should -HaveCount 0 + } + } + } + Context 'Multiple Input' { It 'Positional Parameter' { From dbe73f220fbb4989fb718949acfaf9773ff96c1a Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 15:07:04 +1000 Subject: [PATCH 09/10] Removed Testing Line for E2E test of AppConsentGrantReport Command. --- src/Export-MsIdAppConsentGrantReport.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Export-MsIdAppConsentGrantReport.ps1 b/src/Export-MsIdAppConsentGrantReport.ps1 index 7ff02ec..602508b 100644 --- a/src/Export-MsIdAppConsentGrantReport.ps1 +++ b/src/Export-MsIdAppConsentGrantReport.ps1 @@ -623,4 +623,3 @@ function Export-MsIdAppConsentGrantReport { Main } } -#Export-MsIdAppConsentGrantReport -ExcelWorkbookPath .\report.xlsx From 4e5c84a2d0d9972be52290cb75828eeb4e6bb83e Mon Sep 17 00:00:00 2001 From: Robbie Veivers Date: Fri, 12 Jul 2024 17:19:44 +1000 Subject: [PATCH 10/10] Added More Vebose Error Checks for Missing Module errors --- src/Export-MsIdAppConsentGrantReport.ps1 | 32 ++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Export-MsIdAppConsentGrantReport.ps1 b/src/Export-MsIdAppConsentGrantReport.ps1 index 602508b..b434dfa 100644 --- a/src/Export-MsIdAppConsentGrantReport.ps1 +++ b/src/Export-MsIdAppConsentGrantReport.ps1 @@ -105,11 +105,30 @@ function Export-MsIdAppConsentGrantReport { Write-Verbose "Retrieving ServicePrincipal objects..." WriteMainProgress ServicePrincipal -Status "This can take some time..." -ForceRefresh - $count = Get-MgServicePrincipalCount -ConsistencyLevel eventual + try { + $count = Get-MgServicePrincipalCount -ConsistencyLevel eventual + } + catch [System.Management.Automation.CommandNotFoundException] { + Write-Verbose "$_.Exception.Message" + Write-Error "The Get-MgServicePrincipalCount cmdlet is not available. Please install the latest version of the Microsoft.Graph module." + } + catch { + Write-Verbose "$_.Exception.Message" + } WriteMainProgress ServicePrincipal -ChildPercent 5 -Status "Retrieving $count service principals. This can take some time..." -ForceRefresh Start-Sleep -Milliseconds 500 #Allow message to update $servicePrincipalProps = "id,appId,appOwnerOrganizationId,displayName,appRoles,appRoleAssignmentRequired" - $script:ServicePrincipals = Get-MgServicePrincipal -ExpandProperty "appRoleAssignments" -Select $servicePrincipalProps -All -PageSize 999 + try { + $script:ServicePrincipals = Get-MgServicePrincipal -ExpandProperty "appRoleAssignments" -Select $servicePrincipalProps -All -PageSize 999 + } + catch [System.Management.Automation.CommandNotFoundException] { + Write-Verbose "$_.Exception.Message" + Write-Error "The Get-MgServicePrincipal cmdlet is not available. Please install the latest version of the Microsoft.Graph module." + } + catch { + Write-Verbose "$_.Exception.Message" + } + $appPerms = GetApplicationPermissions @@ -135,7 +154,11 @@ function Export-MsIdAppConsentGrantReport { $object = (Get-MgDirectoryObjectById -Ids $ObjectId) CacheObject -Object $object } + catch [System.Management.Automation.CommandNotFoundException] { + Write-Verbose "$_.Exception.Message" + } catch { + Write-Verbose "$_.Exception.Message" Write-Verbose "Object not found." } } @@ -242,6 +265,11 @@ function Export-MsIdAppConsentGrantReport { $dictFailed.TryAdd($servicePrincipalId, "Failed to add service principal $servicePrincipalId") | Out-Null } } + catch [System.Management.Automation.CommandNotFoundException] { + Write-Verbose "$_.Exception.Message" + Write-Verbose "The Get-MgServicePrincipalOauth2PermissionGrant cmdlet is not available. Please install the latest version of the Microsoft.Graph module." + $dictFailed.TryAdd($servicePrincipalId, $_) | Out-Null + } catch { $dictFailed.TryAdd($servicePrincipalId, $_) | Out-Null }