Public/Add-Cloudockit.ps1

# This script needs to be run by an admin account in your Azure tenant.
# This script will create an Microsoft Entra ID app in your organisation with permission
# to access resources in yours or customers' tenants.


Function Test-CommandExists
{
Param ($command)

 $oldPreference = $ErrorActionPreference
 $ErrorActionPreference = 'stop'
 try {if(Get-Command $command){RETURN $true}}
 Catch {Write-Host "$command does not exist"; RETURN $false}
 Finally {$ErrorActionPreference=$oldPreference}

} #end function test-CommandExistsnd function test-CommandExists



Function Add-ResourcePermission {
    param (
        [Microsoft.Graph.PowerShell.Models.MicrosoftGraphRequiredResourceAccess]$requiredAccess,
        [System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphResourceAccess]]$exposedPermissions,
        [string]$requiredAccesses,
        [string]$permissionType
    )
    
    foreach ($permission in $requiredAccesses.Trim().Split(" ")) {
        $reqPermission = $exposedPermissions | Where-Object { $_.Value -contains $permission }

        Write-Host "Collected information for $($reqPermission.Value) of type $permissionType" -ForegroundColor Green
        $resourceAccess = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphResourceAccess
        $resourceAccess.Type = $permissionType
        $resourceAccess.Id = $reqPermission.Id
        #$requiredAccess.ResourceAccess.Add($resourceAccess)
        $requiredAccess.ResourceAccess += $resourceAccess
    }
}


Function New-AppKey ($appname, $fromDate, $durationInDays) {
    
    $key = @{
        displayName = "Password for $($appname)"
        endDateTime = $fromDate.AddDays($durationInDays)
        startDateTime = $fromDate
    }
    return $key
}


 Function Get-RequiredPermissions {
    

    $requiredApplicationPermissions = 'GroupMember.Read.All','User.Read.All' | Find-MgGraphPermission -ExactMatch -PermissionType Application

    $appPermissions = New-Object -TypeName System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphRequiredResourceAccess]
    $requiredResourceAccess = New-Object -TypeName Microsoft.Graph.PowerShell.Models.MicrosoftGraphRequiredResourceAccess
    $requiredResourceAccess.ResourceAppId =  "00000003-0000-0000-c000-000000000000"

    foreach ($permission in $requiredApplicationPermissions) {
        $requiredResourceAccess.ResourceAccess+=@{ Id = $permission.Id; Type = "Role" }
    }

    $requiredApplicationPermissionDelegated= 'User.Read' | Find-MgGraphPermission -ExactMatch -PermissionType Delegated

    foreach ($permission in $requiredApplicationPermissionDelegated) {
        $requiredResourceAccess.ResourceAccess+=@{ Id = $permission.Id; Type = "Scope" }
    }

    $appPermissions.Add($requiredResourceAccess)

    return $appPermissions
}


function Confirm-MicrosoftGraphServicePrincipal {
    Connect-MgGraph  -Scopes 'Application.Read.All' -TenantId $tenant_id -NoWelcome
    $graphsp = Get-MgServicePrincipal -All | Where-Object {$_.displayname -eq "Microsoft Graph"}
    if (!$graphsp) {
        $graphsp = Get-MgServicePrincipal -SearchString "Microsoft.Azure.AgregatorService"
    }
    if (!$graphsp) {
        Connect-MgGraph  -TenantId $tenant_id -NoWelcome
        New-MgServicePrincipal -ApplId "00000003-0000-0000-c000-000000000000"
        $graphsp = Get-MgServicePrincipal -All | Where-Object {$_.displayname -eq "Microsoft Graph"}
    }
    return $graphsp
}

function Show-Details {
    if ($appName) { Write-Host "===============$appName =====================" }
    if ($tenant_id) { Write-Host "Tenant ID:" $tenant_id}
    if ($tenantName) { Write-Host "Tenant Name:" $tenantName}
    if ($servicePrinId) { Write-Host "ServicePrincipal ID:" $servicePrinId}
}

function Add-Cloudockit {
    # Set ErrorActionPreference to "Stop"
    $ErrorActionPreference = "Stop"
    Try{
      

     try {
        $sessioninfo = Get-CloudDrive
        if ($sessioninfo) {
            $tenant_id =  (Get-AzSubscription)[0].TenantID
            
            If  (-Not(Test-CommandExists Connect-MgGraph)) { Install-Module Microsoft.Graph }
            #Import-Module Microsoft.Graph
            
            Connect-MgGraph -TenantID $env:ACC_TID -NoWelcome -Scopes "Application.ReadWrite.All", "User.Read",  "AppRoleAssignment.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All"
            Write-Host "Connected to MgGraph"

            If  (-Not(Test-CommandExists Connect-AZaccount)) { Install-Module Az }
            #Import-Module Az
            Write-Host "Connect-AZaccount"
            Connect-AzAccount
            Write-Host "Connected to AZaccount"

        }   
     }
     catch {
        [regex] $match = '^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$'
        $i = 0
        do {
                if ($i -gt 0) {
                Write-Host  "The TenantID is in wrong Format, it shoud be a GUID."
            }
    
            $i++;
            $tenant_id = Read-Host "Please enter your Microsoft Entra ID TenantID"

            }until ($tenant_id -match $match)
     
    
        If  (-Not(Test-CommandExists Connect-MgGraph)) {
                Install-Module Microsoft.Graph
                Import-Module Microsoft.Graph
        }

        Connect-MgGraph -TenantID $tenant_id -NoWelcome -Scopes "Application.ReadWrite.All", "User.Read",  "AppRoleAssignment.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All" -UseDeviceCode
        Write-Host "Connected to MgGraph"

        If  (-Not(Test-CommandExists Connect-AZaccount)) { 
                Install-Module Az
                Import-Module Az 
        }
            Connect-AzAccount -UseDeviceAuthentication
            Write-Host "Connected to AZaccount"

    }   

    $appName = ($v = Read-Host "Please enter the wanted name for the App Registration, Default 'Cloudockit_App_Registration' ") ? $v : 'Cloudockit_App_Registration'

    #$appName = Read-Host "Please enter the wanted name for the App Regristration, e.G. 'appname' "

    # [regex] $match = '(https)(:\/\/)([^\s,]+)' #https URL
    # $c=0;
    # do {
    # if ($c -gt 0) {
    # Write-Host "URL Wrong Format"
    # }

    # $c++;
    # $appURI = Read-Host "Please enter the appname URL you received from your appname contact person. It should be start with 'https://'"
    # }until ($appURI -match $match)

    $removeExistingAppWithSameName = $false
    if(!($myApp = Get-MgApplication -Filter "DisplayName eq '$($appName)'"  -ErrorAction SilentlyContinue))
    {

      #Write-Host "Creating application in tenant: $((Get-AzureADTenantDetail).displayName)"
      # Check for the Microsoft Graph Service Principal. If it doesn't exist already, create it.
      $graphsp = Confirm-MicrosoftGraphServicePrincipal 
      
      $existingapp = $null
      $SearchString = "DisplayName:" + $appName
      $existingapp = Get-MgApplication -Search  $SearchString -ConsistencyLevel eventual
      if ($existingapp -and $removeExistingAppWithSameName) {
        Write-Host "Remove-MgApplication" -ForegroundColor red
          Remove-MgApplication -ApplicationId $existingApp.AppId
      }

      $rsps = @()
      if ($graphsp) {
        $rsps += $graphsp

        $tenantDetails = Get-MgOrganization -OrganizationId $tenant_id 
        $tenantName = $tenantDetails.DisplayName

        $fromDate = [System.DateTime]::Now
        $appKey = New-AppKey -appname $appName -fromDate $fromDate -durationInDays 3
        
        # $additionalPaths = @(
        # "/cloudockit/service/",
        # "/cloudockit/service/grants",
        # "/cloudockit/service/signin-oidc"
        # )

        # $redirectUris = foreach ($path in $additionalPaths) {
        # $appURI.trim('/') + $path
        # }

        # $params = @{
        # RedirectUris = $redirectUris
        # ImplicitGrantSettings = @{ EnableIdTokenIssuance = $true }
        # }

        #$ResourceAccessPermissions = Get-RequiredPermissions
 

        Write-Host "Create AppRegistration with Permissions" -ForegroundColor Yellow

      

            New-MgApplication -DisplayName $appName # -RequiredResourceAccess $ResourceAccessPermissions -Web $params
            $myApp = Get-MgApplication -Filter "DisplayName eq '$appName'"
    

            #add secret
            $secret = Add-MgApplicationPassword -ApplicationId $myApp.Id -PasswordCredential $appKey 
            $client_id = $myApp.AppId 

            # Creating the Service Principal for the application
            #$servicePrincipal =
            New-MgServicePrincipal -AppId $myApp.AppId
    
            # grant admin consent
            # $graphSpId = $(Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'").Id

            # foreach ($permission in $ResourceAccessPermissions.ResourceAccess | Where-Object {$_.Type -eq "Role"} ) {

            # Try {
            # New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipal.Id -PrincipalId $servicePrincipal.Id -AppRoleId $permission.Id -ResourceId $graphSpId

            # }
            # catch {
            # Write-Host -foregroundcolor Red "An error occurred: $_"
            # }
            # }

             #delegatedPermissions
            # This is the object ID of the Enterprise Application for Microsoft Graph
            #$graphId = Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'" | Select-Object -ExpandProperty Id

            # Permissions to grant consent to, space separated
            # $scopes = "User.Read"

            # $params = @{
            # ClientId = $servicePrincipal.Id
            # ConsentType = "AllPrincipals"
            # ResourceId = $graphSpId
            # Scope = $scopes
            # }

            # Try {
            # New-MgOauth2PermissionGrant -BodyParameter $params
            # }
            # catch {
            # Write-Host -foregroundcolor Red "An error occurred: $_"
            # }
         
    
            #wait for Azure to have AppRegistrationReady
            $servicePrinId = (Get-AzADServicePrincipal -DisplayName $appName).id
            $waiter = ""
            while($null -eq $servicePrinId)
                {
                    $waiter = $waiter + "."
                    Start-Sleep 2
                    
                    $servicePrinId = (Get-AzADServicePrincipal -DisplayName $appName).id
                    write-host "Waiting for AzADServicePrincipal $appName ..." $waiter
                }
            Remove-Variable waiter
            
            Show-Details
            
            $subscriptions = Get-AzSubscription
            $question = "Add Reader Permission to this Subscription? [y/n]"
            $subscriptions | ForEach-Object {
                Write-Host
                Write-Host -f Green "Subscription: $($_.name)}"
                $confirmation = Read-Host $question
                while($confirmation -ne "y")
                {
                    if ($confirmation -eq 'n') {return}
                    $confirmation = Read-Host $question
                }
                $roleName = "Reader"
                $scope = "/subscriptions/$($_.id)"
                Write-Host $scope
                #New-AzRoleAssignment -ApplicationId $client_id -RoleDefinitionName $roleName -Scope $scope
                New-AzRoleAssignment -ObjectId $servicePrinId -RoleDefinitionName $roleName -Scope $scope
            }
    
            #$URL = "https://login.microsoftonline.com/$tenant_id/adminconsent?client_id=$client_id"
    
            #Start-Process $URL
            $client_secret = $secret.SecretText;

            # $RawPasswordLink = Invoke-WebRequest -Method POST -Body "password=$client_secret&ttl=month" -Uri https://snappass.symplasson.de/ -UseBasicParsing
            # $Link = $RawPasswordLink.RawContent.Substring($RawPasswordLink.RawContent.IndexOf('value="') + 7)
            #$Link = $Link.Substring(0, $link.IndexOf(' ') - 1)

            $appInfo = [pscustomobject][ordered]@{
                    AppName                = $appName
                    TenantName             = $tenantName
                    TenantId               = $tenant_id
                    applicationId          = $client_id
                    applicationSecret      = $client_secret #$Link
                    createDateClientSecret =  $appKey.StartDateTime.ToShortDateString()
                    expirationDateClientSecret = $appKey.endDateTime.ToShortDateString()
                }
         }
        else {
            Write-Host
            Write-Host "Microsoft Graph Service Principal could not be found or created" -ForegroundColor Red
            Write-Host
        }
    }
    else {
        Write-Host
        Write-Host -f Yellow Azure AD Application $appName already exists.
    }



    Write-Host
    Write-Host -f Green "Finished" 

    Show-Details

    Write-Host
    Write-Host "Copy the details from here or find the needed Details in the File AppRegistrationInfo.json, in the current folder"
    $appInfo | Select-Object -Property TenantId, applicationId, applicationSecret
    $appInfo | Select-Object -Property AppName, TenantId, applicationId, applicationSecret, createDateClientSecret, expirationDateClientSecret | ConvertTo-Json >> AppRegistrationInfo.json

    Disconnect-MgGraph | Out-null
    Write-Host
    Write-Host -f Green "Disconnected MgGraph"
    Disconnect-AZaccount | Out-null
    Write-Host
    Write-Host -f Green "Disconnected AZaccount"
    }   
    Catch  {
            Write-Host -foregroundcolor Red "An error occurred: $_"
            Write-Host "Disconnecting..."
            Disconnect-MgGraph | Out-null
            Write-Host
            Write-Host -f Green "Disconnected MgGraph"
            Disconnect-AZaccount | Out-null
            Write-Host
            Write-Host -f Green "Disconnected AZaccount"
    }
    # Reset ErrorActionPreference to default "Continue"
    $ErrorActionPreference = "Continue"

}
# This script needs to be run by an admin account in your Azure tenant.
# This script will create an Microsoft Entra ID app in your organisation with permission
# to access resources in yours or customers' tenants.