TenantToolkit.psm1

function Connect-Graph {
  <#
  .SYNOPSIS
      Authenticates to Microsoft Graph API.
 
  .DESCRIPTION
      This function supports interactive authentication, app-based authentication (using ClientId and ClientSecret), and certificate-based authentication.
 
  .PARAMETER ClientId
      Application (Client) ID for app-based or certificate-based authentication.
 
  .PARAMETER TenantId
      Tenant ID for the Microsoft 365 environment.
 
  .PARAMETER ClientSecret
      Client secret for app-based authentication (SecureString).
 
  .PARAMETER CertificateThumbprint
      Thumbprint of the installed certificate for authentication.
 
  .PARAMETER Interactive
      Switch to explicitly perform interactive authentication.
 
  .PARAMETER Scopes
      Microsoft Graph scopes required for authentication.
 
  .EXAMPLE
      Connect-Graph -Interactive
 
      Explicitly performs interactive authentication.
 
  .EXAMPLE
      $secret = ConvertTo-SecureString "my-secret" -AsPlainText -Force
      Connect-Graph -ClientId "xxxx-xxxx" -TenantId "xxxx-xxxx" -ClientSecret $secret
 
      Authenticate using App credentials.
 
  .EXAMPLE
      Connect-Graph -ClientId "xxxx-xxxx" -TenantId "xxxx-xxxx" -CertificateThumbprint "ABCD1234..."
 
      Authenticate using certificate authentication.
 
  .NOTES
      Requires Microsoft.Graph module.
  #>

  [CmdletBinding(DefaultParameterSetName = 'Interactive')]
  param(
    [Parameter(Mandatory, ParameterSetName = 'App')]
    [Parameter(Mandatory, ParameterSetName = 'Certificate')]
    [string]$ClientId,

    [Parameter(Mandatory, ParameterSetName = 'App')]
    [Parameter(Mandatory, ParameterSetName = 'Certificate')]
    [string]$TenantId,

    [Parameter(Mandatory, ParameterSetName = 'App')]
    [securestring]$ClientSecret,

    [Parameter(Mandatory, ParameterSetName = 'Certificate')]
    [string]$CertificateThumbprint,

    [Parameter(ParameterSetName = 'Interactive')]
    [switch]$Interactive,

    [Parameter()]
    [string[]]$Scopes = @("User.ReadWrite.All", "Group.ReadWrite.All", "Directory.ReadWrite.All")
  )
    
  begin {
    # Check existing context
    if (Get-MgContext) {
      Write-PSFMessage -Level Verbose -Message "Already connected to Microsoft Graph."
      return
    }
  }
  process {
    try {
      switch ($PSCmdlet.ParameterSetName) {
        'Interactive' {
          Write-PSFMessage -Level Verbose -Message "Initiating interactive authentication..."
          Connect-MgGraph -Scopes $Scopes -ErrorAction Stop
          Write-PSFMessage -Level Important -Tag 'Graph.Authentication' -Message "Connected interactively to Microsoft Graph. Scopes: $($Scopes -join ', ')"
        }
        'App' {
          Write-PSFMessage -Level Verbose -Message "Connecting using application credentials..."
          $clientSecretCredential = New-Object System.Management.Automation.PSCredential($ClientId, $ClientSecret)
          Connect-MgGraph -ClientId $ClientId -TenantId $TenantId -ClientSecretCredential $clientSecretCredential -ErrorAction Stop
          Write-PSFMessage -Level Important -Tag 'Graph.Authentication' -Message "Connected using App credentials. Tenant: $TenantId, ClientId: $ClientId"
        }
        'Certificate' {
          Write-PSFMessage -Level Verbose -Message "Connecting using certificate authentication..."
          Connect-MgGraph -ClientId $ClientId -TenantId $TenantId -CertificateThumbprint $CertificateThumbprint -ErrorAction Stop
          Write-PSFMessage -Level Important -Tag 'Graph.Authentication' -Message "Connected using Certificate. Tenant: $TenantId, Thumbprint: $CertificateThumbprint"
        }
      }
    }
    catch {
      Write-PSFMessage -Level Critical -Message "Failed to connect to Microsoft Graph: $_"
      throw $_
    }
  }
  end{
    Write-PSFMessage -Level Info -Message "Connect-Graph exectued successfully."
  }
}