Adding Utility scripts + Setup Documentation
This commit is contained in:
parent
8fe24d44bb
commit
f3bb0212f9
27
00-Setup.md
27
00-Setup.md
|
@ -6,13 +6,34 @@
|
||||||
~~3. Install AzureAD PowerShell Module ...~~
|
~~3. Install AzureAD PowerShell Module ...~~
|
||||||
~~3. Install Microsoft Graph Module ...~~
|
~~3. Install Microsoft Graph Module ...~~
|
||||||
|
|
||||||
2. Working with mcr.microsoft.com/microsoftgraph/powershell docker
|
2. Working with **mcr.microsoft.com/microsoftgraph/powershell** docker
|
||||||
container.
|
container.
|
||||||
Chose this path after failing to setup my personal local
|
Chose this path after failing to setup my personal local
|
||||||
Windows 11 machine with the above libraries, realizing this should
|
Windows 11 machine with the above libraries, realizing this should
|
||||||
have been my first choice.
|
have been my first choice.
|
||||||
|
|
||||||
3. Tested connection from within the docker conatiner:
|
NOTE: All console actions described below are from within the docker
|
||||||
|
container.
|
||||||
|
All Web UI action were done on my personal machine. I do not describe
|
||||||
|
the process of copying over the file from the container / remote
|
||||||
|
machine into my local-browser machine.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
.../varonis $
|
# bash command line:
|
||||||
|
docker run --rm -it -v "$PWD/data:/data" \
|
||||||
|
-v "$PWD/data/.dotnet:/root/.dotnet" \
|
||||||
|
-v "$PWD/src:/data/src" \
|
||||||
|
-w "/data" \
|
||||||
|
mcr.microsoft.com/microsoftgraph/powershell
|
||||||
```
|
```
|
||||||
|
|
||||||
|
3. Following [this tutorial page](https://learn.microsoft.com/en-us/graph/tutorials/powershell-app-only?tabs=linux-macos&tutorial-step=1#register-application-for-app-only-authentication)
|
||||||
|
I've created the following utility scripts to help with this process:
|
||||||
|
|
||||||
|
1. [`Create-Cert`](Create-Cert.ps1) -
|
||||||
|
Create a self-signed certificate and load it into the .NET
|
||||||
|
cert-store (see Load-Cert next).
|
||||||
|
2. [`Load-Cert`](Load-Cert.ps1) -
|
||||||
|
Load certificate files into the local .NET cert-store.
|
||||||
|
3. [`Connect-AppCert`](Connect-AppCert.ps1) -
|
||||||
|
This will be used to establish a new app connection.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
$clientId='56cb6a8c-92bc-484d-8919-b03af7cf4e80'
|
||||||
|
$tenantID='6b4b1b0d-23f1-4063-bbbd-b65e2984b893'
|
||||||
|
$Cert = ./src/Load-Cert.ps1
|
||||||
|
$certThumb=$Cert.Thumbprint
|
||||||
|
Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumb $certThumb
|
|
@ -0,0 +1,78 @@
|
||||||
|
# Following guide on:
|
||||||
|
# <https://learn.microsoft.com/en-us/graph/tutorials/powershell-app-only?tabs=linux-macos&tutorial-step=1>
|
||||||
|
#
|
||||||
|
# This script creates a new
|
||||||
|
[CmdletBinding()]param([switch]$Force) # This adds common parameters, like ErrorAction
|
||||||
|
|
||||||
|
$local:Create = -not (
|
||||||
|
(Test-Path 'powershell-app.pem') -and
|
||||||
|
(Test-Path 'powershell-app.crt') -and
|
||||||
|
(Test-Path 'powershell-app.key')
|
||||||
|
)
|
||||||
|
if( $Force -or $Create ) {
|
||||||
|
foreach( $local:ext in @('.key', '.pem', '.crt', '.pfx') ) {
|
||||||
|
if( Test-Path "powershell-app${ext}" ) {
|
||||||
|
Remove-Item -Force -LiteralPath "powershell-app${ext}" -Verbose
|
||||||
|
$Create = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( $Create ) {
|
||||||
|
# Create private key
|
||||||
|
& openssl genrsa -des3 -out powershell-app.key `
|
||||||
|
-passout "pass:keypassphrase" `
|
||||||
|
2048
|
||||||
|
# -passout pass:... usage is ONLY acceptable in insecure testing env.
|
||||||
|
|
||||||
|
# Create Signed Certificate with DES3 Encryption (with an INSECURE passkey)
|
||||||
|
& openssl req -x509 `
|
||||||
|
-key 'powershell-app.key' -passin "pass:keypassphrase" `
|
||||||
|
-sha256 -days 365 -subj '/CN=PowerShell App-Only' `
|
||||||
|
-out 'powershell-app.crt' `
|
||||||
|
-passout "pass:pempassphrase"
|
||||||
|
# -passin/passout pass:... usage is ONLY acceptable in insecure
|
||||||
|
# testing env.
|
||||||
|
|
||||||
|
# Expose the public key for easy copying by non-root users
|
||||||
|
chmod 664 'powershell-app.crt'
|
||||||
|
|
||||||
|
if( Test-Path 'powershell-app.pfx' ) { Remove-Item 'powershell-app.pfx' }
|
||||||
|
|
||||||
|
Write-Host -ForegroundColor Green "`nKEY, PEM and CRT certificate files created`n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if( -not (Test-Path 'powershell-app.pfx') ) {
|
||||||
|
$Create = $true
|
||||||
|
# Self-Sign Certificate Request
|
||||||
|
& openssl pkcs12 -export -in 'powershell-app.crt' `
|
||||||
|
-inkey 'powershell-app.key' -passin "pass:keypassphrase"`
|
||||||
|
-out 'powershell-app.pfx' -passout "pass:pfxpassphrase"
|
||||||
|
# -passin/passout pass:... usage is ONLY acceptable in insecure
|
||||||
|
# testing env.
|
||||||
|
|
||||||
|
Write-Host -ForegroundColor Green "`nPFX certificate file created`n"
|
||||||
|
Write-Host "You can now load certificate by running ./src/Load-Cert.ps1"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host -ForegroundColor Red "NOTE: You will need to register this certifcate!"
|
||||||
|
Write-Host "Grab the powershell-app.crt public key file and Follow"
|
||||||
|
Write-Host "instructions in the tutorial link below: (very long link)"
|
||||||
|
Write-Host " https://learn.microsoft.com/en-us/graph/tutorials/powershell-app-only?tabs=linux-macos&tutorial-step=1#register-application-for-app-only-authentication"
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
$Cert = ./src/Load-Cert.ps1 -Force:$Create
|
||||||
|
Write-Host -ForegroundColor Green "Certificate loaded with ./src/Load-Cert.ps1"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host -ForegroundColor Yellow "Recommendation:"
|
||||||
|
Write-Host "If you haven't already, it is recommended you create a script "
|
||||||
|
Write-Host "./src/Connect-AppCert.ps1 to quickly connect. It should have at"
|
||||||
|
Write-Host "least the following content:"
|
||||||
|
Write-Host "########################################################################################"
|
||||||
|
Write-Host "`$clientId='<Client ID of the Application>' # Get this from the Azure Portal"
|
||||||
|
Write-Host "`$tenantID='<Tenant ID of Azure AD>' # Get this from the Azure Portal"
|
||||||
|
Write-Host "`$certThumb='$($Cert.Thumbprint )' # grabbed from ./src/Load-Cert.ps1"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host 'Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumb $certThumb'
|
||||||
|
Write-Host "########################################################################################"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "NOTE that Connect-AppCert.ps1 is listed in .gitignore and will not be saved to the git repo due to it's sensitive nature."
|
|
@ -0,0 +1,61 @@
|
||||||
|
using namespace System.Security.Cryptography.X509Certificates
|
||||||
|
[CmdletBinding()]param([switch]$Force) # This adds common parameters, like ErrorAction
|
||||||
|
|
||||||
|
# Code from https://stackoverflow.com/a/42108420/799379
|
||||||
|
# Since this is mimicing a C# clause, the verb isn't an approved one.
|
||||||
|
# If you see a Warning, it's OK. This was an intentional choice.
|
||||||
|
function Using-Object {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position=0)]
|
||||||
|
[AllowEmptyString()]
|
||||||
|
[AllowEmptyCollection()]
|
||||||
|
[AllowNull()]
|
||||||
|
[Object]
|
||||||
|
$InputObject,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true, Position=1)]
|
||||||
|
[scriptblock]
|
||||||
|
$ScriptBlock
|
||||||
|
)
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Invoke-Command $ScriptBlock
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ($InputObject -is [System.IDisposable])
|
||||||
|
{
|
||||||
|
$InputObject.Dispose()
|
||||||
|
Write-Verbose "IDisposable Disposed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Using-Object ([X509Store]::new('My', 'CurrentUser', 'ReadWrite') | Tee-Object -Variable store) {
|
||||||
|
$local:Cert = $store.Certificates |
|
||||||
|
Where-Object Subject -eq "CN=PowerShell App-Only"
|
||||||
|
if( $tst -and $Force ) {
|
||||||
|
$store.Remove($Cert);
|
||||||
|
$Cert = $null
|
||||||
|
}
|
||||||
|
if( -not $Cert ) {
|
||||||
|
$store.Add([X509Certificate2]::new(
|
||||||
|
'./powershell-app.pfx',
|
||||||
|
"pfxpassphrase", # BAD PRACTICE: Hard coded - BEWARE
|
||||||
|
[X509KeyStorageFlags]::PersistKeySet)
|
||||||
|
)
|
||||||
|
|
||||||
|
$Cert = $store.Certificates |
|
||||||
|
Where-Object Subject -eq "CN=PowerShell App-Only"
|
||||||
|
|
||||||
|
if( -not $Cert ) {
|
||||||
|
throw "Failed to create certificate"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host -ForegroundColor Green "Certificate created"
|
||||||
|
}
|
||||||
|
$Cert
|
||||||
|
}
|
||||||
|
$store = $null
|
Loading…
Reference in New Issue