Skip to content

Commit

Permalink
all files added (#30)
Browse files Browse the repository at this point in the history
added all files that were used / shown at PSConfEU22

Co-authored-by: Andreas Hähnel <[email protected]>
  • Loading branch information
M365-Architect and Andreas Hähnel authored Jun 25, 2022
1 parent dd9ac47 commit 90cde37
Show file tree
Hide file tree
Showing 18 changed files with 458 additions and 0 deletions.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Connect-AzureAD #Module AzureAD required!
# https://docs.microsoft.com/en-us/powershell/microsoftgraph/azuread-msoline-cmdlet-map
$myAppRegistration = 'PSConfEU-Exchange'
$appHomepageURL = 'https://localhost:12345'
$appReplyURL = 'https://localhost:12345/signin-oidc'
$myCoolApp = New-AzureADApplication -DisplayName $myAppRegistration -AvailableToOtherTenants $false -Homepage $appHomePageUrl -ReplyUrls @($appReplyUrl)
# New-MgApplication
# now create the Service Principal from that app
$myEnterpriseApp = New-AzureADServicePrincipal -AppId $myCoolApp.AppID -Tags @(WindowsAzureActiveDirectoryIntegratedApp,PSConfEU)
# New-MgServicePrincipal

# now be happy with Conditional Access
# afterwards grant Graph permissions
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Connect-AzureAD #Module AzureAD required!
$myAppRegistrationID = "<YOUR APP ID>"
$newSecret = New-AzureADApplicationPasswordCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PowerShellGenerated" -StartDate (get-date) -endDate (get-date).AddDays(720)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
$myAppRegistrationID = "<YOUR APP ID>"
New-SelfSignedCertificate -Subject "CN=PSConfEUCertificate" -KeySpec Signature -CertStoreLocation "cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -NotAfter (Get-Date).AddYears(10)
$thumbprint = (Get-ChildItem "cert:\CurrentUser\My" | Where-Object {$_.Subject -eq "CN=PSConfEUCertificate"}).Thumbprint
if ($tmppath -eq $false) {New-Item C:\cert -ItemType Directory}

#PFX
$certPW = "myUncrackableSecret123!"
$certPW = ConvertTo-SecureString -String $certPW -Force -AsPlainText
Export-PfxCertificate -cert "cert:\CurrentUser\my\$thumbprint" -FilePath C:\cert\PSConfEUCertificate.pfx -Password $certPW
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\cert\PSConfEUCertificate.pfx", $certPW)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
New-AzureADApplicationKeyCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PSConfEU" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
# New-MgApplicationKey

#CER
Get-ChildItem "Cert:\CurrentUser\My\$thumbprint" | Export-Certificate -FilePath "C:\cert\PSConfEUCertificate.cer"
$CERcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\cert\PSConfEUCertificate.cer")
$keyValue = [System.Convert]::ToBase64String($CERcert.GetRawCertData())
New-AzureADApplicationKeyCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PSConfEU" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
# New-MgApplicationKey
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$myAppRegistrationID = "<YOUR APP ID>" #AppID, not ObjectID!
New-ApplicationAccessPolicy -AppId $myAppRegistrationID -PolicyScopeGroupId "[email protected]" -AccessRight RestrictAccess -Description "Restrict this app to members of this security or distribution group"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$found = $false
while (-not $found)
{
$user = $allUsers.Value | Where-Object {$_.proxyaddresses -ilike ("*" + $owner.Email + "*")}
if($user){$found = $true;break}
$uri = $allUsers.'@odata.nextLink'
$allUsers = Invoke-RestMethod -Method Get -Uri $uri -ContentType 'application/json' -Headers $script:APIHeader
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#========================================================================
# Created on: 16.06.2022 19:02
# Created by: Andreas Hähnel
# Organization: Black Magic Cloud
# Function name: 99_ExchangeOnlineSampleScript_Native.ps1
# Script Version: 0.1
#========================================================================
# RequiredPermissions:
# Delegated (work or school account) Not supported.
# Delegated (personal Microsoft account) Not supported.
# Application Mail.ReadWrite
#
# Grant admin consent for the tenant
#
#========================================================================
# Description:
# this script reads the contents from the inbox of a specified mailbox
# and exports the content as XML
#
#========================================================================
# Useful links:
#
#
#========================================================================
#
# Changelog:
# Version 0.1 16.06.2022
# - initial creation
#
#========================================================================
#
# EXAMPLE (replace variables with actual values):
#
#========================================================================
# TODO:
# - add logging
#========================================================================

#========================================================================
# Global Variables
#========================================================================
#region global variables
$TargetMailboxes = @("UPN OF YOUR MAILBOX")

New-Variable -Name appID -Value "<ID OF YYOUR APP>" -Option ReadOnly
New-Variable -Name tenantID -Value "<ID OF YOUR AAD>" -Option ReadOnly
New-Variable -Name clientSecret -Value "<SECRET OF YOUR APP>" -Option ReadOnly

#endregion

#========================================================================
# Functions
#========================================================================
#region functions
function Get-GraphAuthorizationToken {
param
(
[string]$ResourceURL = 'https://graph.microsoft.com',
[string][parameter(Mandatory)] $TenantID,
[string][Parameter(Mandatory)] $ClientKey,
[string][Parameter(Mandatory)] $AppID
)

$Authority = "https://login.windows.net/$TenantID/oauth2/token"
[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
$EncodedKey = [System.Web.HttpUtility]::UrlEncode($ClientKey)
$body = "grant_type=client_credentials&client_id=$AppID&client_secret=$EncodedKey&resource=$ResourceUrl"
# Request a Token from the graph api
$result = Invoke-RestMethod -Method Post -Uri $Authority `
-ContentType 'application/x-www-form-urlencoded' -Body $body
$script:APIHeader = @{ 'Authorization' = "Bearer $($result.access_token)" }
}
#========================================================================

function Normalize-String {
param(
[Parameter(Mandatory = $true)][string]$str
)

$str = $str.ToLower()
$str = $str.Replace(" ", "")
$str = $str.Replace("ä", "ae")
$str = $str.Replace("ö", "oe")
$str = $str.Replace("ü", "ue")
$str = $str.Replace("ß", "ss")
$str = $str.Replace("?","")

Write-Output $str
}
#========================================================================
#endregion

#========================================================================
# Scriptstart
#========================================================================
Get-GraphAuthorizationToken -AppID $appID -TenantID $tenantID -ClientKey $clientSecret

foreach($mailbox in $TargetMailboxes)
{
$uri = "https://graph.microsoft.com/v1.0/users/$mailbox/mailFolders/Inbox"
#in v1.0 you need to use the well-known name, in beta there is a parameter wellKnownName
$EmailFolderInbox = Invoke-RestMethod -Uri $uri -Method Get -Headers $script:APIHeader

#list all emails in the inbox
$uri = "https://graph.microsoft.com/v1.0/users/$mailbox/mailFolders/$($EmailFolderInbox.id)/messages"
$allMails = Invoke-RestMethod -Uri $uri -Method Get -Headers $script:APIHeader

#export all emails to 1 comprehensive XML
$allMails | Export-Clixml -Path "C:\dev\allmails.xml"
#each email to a single XML and delete it
foreach($mail in $allMails.value) #if you need to spend some hours of debugging, forget ".value" :)
{
$mail | Export-Clixml -Path "C:\dev\$(Normalize-String $mail.Subject).xml" -Force
$uri = "https://graph.microsoft.com/v1.0/users/$mailbox/mailFolders/$($EmailFolderInbox.id)/messages/$($mail.id)"
Invoke-RestMethod -Uri $uri -Method DELETE -Headers $script:APIHeader
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#========================================================================
# Created on: 16.06.2022 19:02
# Created by: Andreas Hähnel
# Organization: Black Magic Cloud
# Function name: 99_ExchangeOnlineSampleScript_GraphSDK.ps1
# Script Version: 0.1
#========================================================================
# RequiredPermissions:
# Delegated (work or school account) Not supported.
# Delegated (personal Microsoft account) Not supported.
# Application Mail.ReadWrite
#
# Grant admin consent for the tenant
#
#========================================================================
# Description:
# this script reads the contents from the inbox of a specified mailbox
# and exports the content as XML
#
#========================================================================
# Useful links:
#
#
#========================================================================
#
# Changelog:
# Version 0.1 16.06.2022
# - initial creation
#
#========================================================================
#
# EXAMPLE (replace variables with actual values):
#
#========================================================================
# TODO:
# - add logging
#========================================================================

Import-Module Microsoft.Graph.Mail
Import-Module Microsoft.Graph.Authentication

New-Variable -Name appID -Value "<ID OF YOUR APP>" -Option ReadOnly
New-Variable -Name tenantID -Value "<ID OF YOUR AAD>" -Option ReadOnly

# Graph SDK only supports certificate based auth for unattended scripts, no secret (currently):
# https://docs.microsoft.com/en-us/powershell/microsoftgraph/app-only?view=graph-powershell-1.0&tabs=powershell


Connect-MgGraph -Scopes Mail.Read.Shared,User.Read.All -ClientId $appID -TenantId $tenantID -
$user = Get-MgUser -Search '"DisplayName:Spiderman"' -ConsistencyLevel eventual
#$inbox = Get-MgUserMailFolder -UserId $user.Id | Where-Object {$_.DisplayName -eq "Inbox"}

$allMails = Get-MgUserMessage -UserId $user.Id
$allMails | Export-Clixml -Path "C:\dev\allmails.xml"
foreach($mail in $allMails.Value)
{
$mail | Export-Clixml -Path "C:\dev\$($mail.Subject).xml"
#here you can use the UPN
#Remove-MgUserMessage -UserId $user.Id -MessageId $mail.id
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
$mailbox = "<UPN OF YOUR MAILBOX>"

New-Variable -Name appID -Value "<ID OF YOUR APP>" -Option ReadOnly
New-Variable -Name tenantID -Value "<ID OF YOUR AAD>" -Option ReadOnly
New-Variable -Name clientSecret -Value "<SECRET OF YOUR APP>" -Option ReadOnly

function Get-GraphAuthorizationToken {
param
(
[string]$ResourceURL = 'https://graph.microsoft.com',
[string][parameter(Mandatory)] $TenantID,
[string][Parameter(Mandatory)] $ClientKey,
[string][Parameter(Mandatory)] $AppID
)

$Authority = "https://login.windows.net/$TenantID/oauth2/token"
[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
$EncodedKey = [System.Web.HttpUtility]::UrlEncode($ClientKey)
$body = "grant_type=client_credentials&client_id=$AppID&client_secret=$EncodedKey&resource=$ResourceUrl"
# Request a Token from the graph api
$result = Invoke-RestMethod -Method Post -Uri $Authority `
-ContentType 'application/x-www-form-urlencoded' -Body $body
$script:APIHeader = @{ 'Authorization' = "Bearer $($result.access_token)" }
}

Get-GraphAuthorizationToken -TenantID $tenantID -AppID $appID -ClientKey $clientSecret

$uri = "https://graph.microsoft.com/v1.0/users/$mailbox/mailFolders/Inbox"

$EmailFolderInboxIRM = Invoke-RestMethod -Uri $uri -Method Get -Headers $script:APIHeader
$EmailFolderInboxIWR = Invoke-WebRequest -Uri $uri -Method Get -Headers $script:APIHeader

#get the body:
$EmailFolderInboxIWR.Content | Convertfrom-Json
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Connect-AzureAD #Module AzureAD required!
# https://docs.microsoft.com/en-us/powershell/microsoftgraph/azuread-msoline-cmdlet-map
$myAppRegistration = 'PSConfEU22'
$appHomepageURL = 'https://localhost:12345'
$appReplyURL = 'https://localhost:12345/signin-oidc'
$myCoolApp = New-AzureADApplication -DisplayName $myAppRegistration -AvailableToOtherTenants $false -Homepage $appHomePageUrl -ReplyUrls @($appReplyUrl)
# New-MgApplication
# now create the Service Principal from that app
$myEnterpriseApp = New-AzureADServicePrincipal -AppId $myCoolApp.AppID -Tags @(WindowsAzureActiveDirectoryIntegratedApp,PSConfEU)
# New-MgServicePrincipal

# now be happy with Conditional Access
# afterwards grant Graph permissions
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Connect-AzureAD #Module AzureAD required!
$myAppRegistrationID = "<ID OF YOUR APP>"
$newSecret = New-AzureADApplicationPasswordCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PowerShellGenerated" -StartDate (get-date) -endDate (get-date).AddDays(720)
# Add-MgApplicationPassword
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
$myAppRegistrationID = "<ID OF YOUR APP>"
New-SelfSignedCertificate -Subject "CN=PSConfEUCertificate" -KeySpec Signature -CertStoreLocation "cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -NotAfter (Get-Date).AddYears(10)
$thumbprint = (Get-ChildItem "cert:\CurrentUser\My" | Where-Object {$_.Subject -eq "CN=PSConfEUCertificate"}).Thumbprint
if ($tmppath -eq $false) {New-Item C:\cert -ItemType Directory}

#PFX
$certPW = "myUncrackableSecret123!"
$certPW = ConvertTo-SecureString -String $certPW -Force -AsPlainText
Export-PfxCertificate -cert "cert:\CurrentUser\my\$thumbprint" -FilePath C:\cert\PSConfEUCertificate.pfx -Password $certPW
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\cert\PSConfEUCertificate.pfx", $certPW)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
New-AzureADApplicationKeyCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PSConfEU" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
# New-MgApplicationKey

#CER
Get-ChildItem "Cert:\CurrentUser\My\$thumbprint" | Export-Certificate -FilePath "C:\cert\PSConfEUCertificate.cer"
$CERcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\cert\PSConfEUCertificate.cer")
$keyValue = [System.Convert]::ToBase64String($CERcert.GetRawCertData())
New-AzureADApplicationKeyCredential -ObjectId $myAppRegistrationID -CustomKeyIdentifier "PSConfEU" -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
# New-MgApplicationKey
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$myAppRegistrationID = "<ID OF YOUR APP>" #AppID, not ObjectID!
New-ApplicationAccessPolicy -AppId $myAppRegistrationID -PolicyScopeGroupId "[email protected]" -AccessRight RestrictAccess -Description "Restrict this app to members of this security or distribution group"
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
$SiteCollectionRelativePath = "<YOURTENANT>.sharepoint.com:/sites/PSConfEU22"
$tenantID = "<ID OF YOUR AAD>"
#Worker App
$appID = "<ID OF YOUR WORKER APP>"
#Admin App
$secretAdminApp = "<SECRET OF YOUR ADMIN APP>"
$appIDAdminApp = "<ID OF YOUR ADMIN APP>"


function Get-GraphAuthorizationToken {
param
(
[string]$ResourceURL = 'https://graph.microsoft.com',
[string][parameter(Mandatory)]$TenantID,
[string][Parameter(Mandatory)]$ClientKey,
[string][Parameter(Mandatory)]$AppID
)

$Authority = "https://login.windows.net/$TenantID/oauth2/token"

[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
$EncodedKey = [System.Web.HttpUtility]::UrlEncode($ClientKey)

$body = "grant_type=client_credentials&client_id=$AppID&client_secret=$EncodedKey&resource=$ResourceUrl"

# Request a Token from the graph api
$result = Invoke-RestMethod -Method Post -Uri $Authority -ContentType 'application/x-www-form-urlencoded' -Body $body

$script:APIHeader = @{ 'Authorization' = "Bearer $($result.access_token)" }
}

Get-GraphAuthorizationToken -TenantID $tenantID -AppID $appIDAdminApp -ClientKey $secretAdminApp

$uri = "https://graph.microsoft.com/v1.0/sites/$SiteCollectionRelativePath"
$GraphResultSiteCollection = Invoke-RestMethod -Method Get -Uri $uri -Headers $script:APIHeader
$siteID = $GraphResultSiteCollection.id.Split(",")[1]

$body = @"
{
"roles": ["write"],
"grantedToIdentities": [
{
"application": {
"id": "$appID",
"displayName": "PSConfEU22"
}
}
]
}
"@

$uri = "https://graph.microsoft.com/v1.0/sites/$siteID/permissions"

# and store the permissions for the app:
Invoke-RestMethod -Method Post -uri $uri -Headers $script:APIHeader -Body $body -ContentType "application/json; charset=utf-8"
Loading

0 comments on commit 90cde37

Please sign in to comment.