MsolServicePrincipal

Rising Flight 5,256 Reputation points
2025-07-31T21:45:27.7066667+00:00

Hi All,

How can I connect to Azure AD and execute the scripts below? I am getting errors when running them. I was able to connect earlier, but now Connect-AzureAD is deprecated. Please guide me.

$applist = Get-MsolServicePrincipal -all  |Where-Object -FilterScript { ($_.DisplayName -notlike "*Microsoft*") -and ($_.DisplayName -notlike "autohost*") -and  ($_.ServicePrincipalNames -notlike "*localhost*") }
foreach ($appentry in $applist) {
    $principalId = $appentry.AppPrincipalId
    $principalName = $appentry.DisplayName

    Get-MsolServicePrincipalCredential -AppPrincipalId $principalId -ReturnKeyValues $false | ? { $_.Type -eq "Password" } | % { "$principalName;$principalId;" + $_.KeyId.ToString() +";" + $_.StartDate.ToString() + ";" + $_.EndDate.ToString() } | out-file -FilePath C:\temp\output.txt -append
}

$clientId = '12345asd-avf5-hy78-asd5-9a71fa0a4024'
$bytes = New-Object Byte[] 32
$rand = [System.Security.Cryptography.RandomNumberGenerator]::Create() 
$rand.GetBytes($bytes)
$rand.Dispose()
$newClientSecret = [System.Convert]::ToBase64String($bytes)
New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Sign -Value $newClientSecret -StartDate (Get-Date) -EndDate (Get-Date).AddYears(1)
New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Verify -Value $newClientSecret -StartDate (Get-Date) -EndDate (Get-Date).AddYears(1)
New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Password -Usage Verify -Value $newClientSecret -StartDate (Get-Date) -EndDate (Get-Date).AddYears(1)
$newClientSecret

Microsoft Security | Microsoft Entra | Microsoft Entra External ID
{count} votes

2 answers

Sort by: Most helpful
  1. Marcin Policht 53,825 Reputation points MVP Volunteer Moderator
    2025-07-31T21:54:11.25+00:00

    Connect-AzureAD is deprecated, but so is the entire MSOnline module (which includes Get-MsolServicePrincipal and New-MsolServicePrincipalCredential). These cmdlets should be replaced with Microsoft Graph PowerShell equivalents. The caveat is that Microsoft has not provided 1-to-1 replacements for all MSOnline cmdlets yet — especially Get-MsolServicePrincipalCredential and New-MsolServicePrincipalCredential. So, you'll need to work within the supported tooling using Microsoft Graph PowerShell SDK, which connects via Connect-MgGraph.

    1. Install Microsoft Graph PowerShell, if not already installed:
    Install-Module Microsoft.Graph -Scope CurrentUser
    

    Then import the module:

    Import-Module Microsoft.Graph
    
    1. Connect to Microsoft Entra ID
    Connect-MgGraph -Scopes "Application.Read.All", "Application.ReadWrite.All"
    

    You’ll need to consent to permissions. These can be delegated or app-based.


    1. List all applications (service principals)
    $appList = Get-MgServicePrincipal -All | Where-Object {
        $_.DisplayName -notlike "*Microsoft*" -and
        $_.DisplayName -notlike "autohost*" -and
        $_.ServicePrincipalNames -notlike "*localhost*"
    }
    
    1. List app credentials (App Secrets / Certificates)
    foreach ($app in $appList) {
        $creds = Get-MgServicePrincipal -ServicePrincipalId $app.Id |
                 Select-Object -ExpandProperty PasswordCredentials
    
        foreach ($cred in $creds) {
            "$($app.DisplayName);$($app.AppId);$($cred.KeyId);$($cred.StartDateTime);$($cred.EndDateTime)" |
                Out-File -FilePath "C:\temp\output.txt" -Append
        }
    }
    

    If there are certificates (not just secrets), use KeyCredentials property instead of PasswordCredentials.

    1. Add a new client secret

    To generate and add a new password credential:

    $clientId = "12345asd-avf5-hy78-asd5-9a71fa0a4024"
    $bytes = New-Object byte[] 32
    [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
    $newClientSecret = [Convert]::ToBase64String($bytes)
    
    $params = @{
        PasswordCredential = @{
            DisplayName    = "Auto-generated secret"
            EndDateTime    = (Get-Date).AddYears(1).ToString("o")
            StartDateTime  = (Get-Date).ToString("o")
            SecretText     = $newClientSecret
        }
    }
    
    # This is for an Application (not ServicePrincipal)
    Add-MgApplicationPassword -ApplicationId $clientId -BodyParameter $params.PasswordCredential
    
    # Output the secret for use
    $newClientSecret
    

    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin


  2. Marcin Policht 53,825 Reputation points MVP Volunteer Moderator
    2025-08-04T01:23:46.6+00:00

    The error you're getting seems to indicate that the ApplicationId (i.e., Client ID) you're using is not being recognized by Graph as an existing application object. This can happen for a number of reasons, but the most likely ones include:

    1. You're using a Service Principal ID (object in the ServicePrincipal directory) instead of the Application ID (from App Registrations).
      • Add-MgApplicationPassword only works on application objects — not service principals.
    2. The app was registered in a different tenant than the one you're connected to.
    3. You're authenticated but lack sufficient permissions (Application.ReadWrite.All on App Registration).

    First, confirm you’re using the right object. You can verify the app exists like this:

    # Connect if not already connected
    Connect-MgGraph -Scopes "Application.Read.All", "Application.ReadWrite.All"
    
    # Check for application by AppId (Client ID)
    Get-MgApplication -Filter "appId eq '12345asd-avf5-hy78-asd5-9a71fa0a4024'"
    

    If you get a result: that’s the correct object to use in Add-MgApplicationPassword. Otherwise, you're using a Service Principal or the app is in a different tenant. Note that Get-MgApplication searches App Registrations (application objects) and Get-MgServicePrincipal searches Enterprise Applications (service principal objects).

    If you are using a Service Principal ID, retrieve the corresponding Application ID

    # Suppose you have the Service Principal object ID
    $sp = Get-MgServicePrincipal -Filter "appId eq '12345asd-avf5-hy78-asd5-9a71fa0a4024'"
    $sp.AppId  # This is the correct ApplicationId for Add-MgApplicationPassword
    

    Now plug that AppId into your Add-MgApplicationPassword command.

    $clientId = "<actual AppId from App Registrations>"  # NOT the ObjectId or SP object
    
    # Generate secure random secret
    $bytes = New-Object byte[] 32
    [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
    $newClientSecret = [Convert]::ToBase64String($bytes)
    
    # Prepare credential
    $params = @{
        PasswordCredential = @{
            DisplayName    = "Auto-generated secret"
            EndDateTime    = (Get-Date).AddYears(1).ToString("o")
            StartDateTime  = (Get-Date).ToString("o")
            SecretText     = $newClientSecret
        }
    }
    
    # Add the secret
    Add-MgApplicationPassword -ApplicationId $clientId -BodyParameter $params.PasswordCredential
    
    # Output the value
    $newClientSecret
    

    Make sure you've consented to the required Graph scopes. At minimum:

    • Application.Read.All
    • Application.ReadWrite.All

    For script automation or non-interactive contexts, consider setting up an Entra ID app registration with application permissions and using Connect-MgGraph -ClientId ... -TenantId ... -CertificateThumbprint ... for automation.


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.