Skip to content

Van PowerShell tot Smart Home

Van PowerShell tot Smart Home

Primary Menu
  • Algemeen
  • Fotografie
  • Home Assistant
  • Microsoft
  • Azure
  • Powershell
Light/Dark Button
  • Home
  • Powershell : Tijdelijke toegang zonder gedoe: Temporary Access Pass automatiseren
  • Azure
  • Powershell

Powershell : Tijdelijke toegang zonder gedoe: Temporary Access Pass automatiseren

Vincent van Unen 2026-03-13 (Last updated: 2026-03-13) 9 minutes read
ChatGPT Image Mar 13, 2026, 10_06_00 AM

Iedere beheerder kent het wel.

Een gebruiker kan niet meer inloggen omdat:

  • de telefoon met Microsoft Authenticator verdwenen is 📱
  • MFA opnieuw ingesteld moet worden
  • een nieuwe medewerker nog geen MFA heeft ingesteld

Dan begint vaak het bekende proces van MFA resetten of tijdelijke toegang regelen.

Gelukkig heeft Microsoft hiervoor een uitstekende oplossing: Temporary Access Pass (TAP).

Met een TAP kan een gebruiker tijdelijk inloggen en bijvoorbeeld MFA opnieuw instellen. Maar als beheerder wil je dit natuurlijk consistent, veilig en geautomatiseerd configureren.

Daarom heb ik een PowerShell script gemaakt dat de TAP-policy automatisch configureert via Microsoft Graph.

Inclusief:

  • automatische installatie van Microsoft Graph
  • parametercontrole
  • logging
  • transcript logging voor Intune
  • verificatie van de configuratie

Wat is een Temporary Access Pass?

Een Temporary Access Pass is een tijdelijke toegangscode binnen Microsoft Entra ID waarmee een gebruiker kan:

  • MFA opnieuw registreren
  • een nieuwe authenticator-app instellen
  • toegang krijgen tot het account zonder bestaande MFA
  • een nieuw apparaat configureren

Je kunt het zien als een tijdelijke sleutel tot de voordeur van een account.

De TAP is bewust tijdelijk en kan worden ingesteld met:

  • een minimale geldigheid
  • een maximale geldigheid
  • een code lengte
  • eenmalig gebruik

Juist deze instellingen bepalen hoe veilig en gebruiksvriendelijk je omgeving is.

TAP + MFA flow

Onderstaand diagram laat zien hoe TAP werkt in combinatie met MFA.

Flow uitgelegd

1️⃣ Beheerder maakt een Temporary Access Pass
2️⃣ De gebruiker ontvangt de tijdelijke code
3️⃣ Gebruiker logt in met TAP
4️⃣ Microsoft Entra valideert de code
5️⃣ MFA registratie wordt gestart
6️⃣ TAP wordt ongeldig

Na deze stappen gebruikt de gebruiker weer normale MFA authenticatie.

Verbinding maken met Microsoft Graph

Het script gebruikt Microsoft Graph om de TAP-policy te wijzigen.

Dit gebeurt met:

Connect-MgGraph -Scopes "Policy.ReadWrite.AuthenticationMethod"

Wanneer het script voor het eerst wordt uitgevoerd, verschijnt er een Microsoft loginvenster.

Microsoft login scherm

Hier log je in met een account dat voldoende rechten heeft.

Bijvoorbeeld:

  • Global Administrator
  • Authentication Administrator
  • Privileged Authentication Administrator

Toestemming geven aan Microsoft Graph

Omdat het script policies wijzigt, moet Microsoft Graph toestemming krijgen.

Het belangrijkste recht is:

Policy.ReadWrite.AuthenticationMethod

Dit geeft toegang tot authentication method policies, waaronder Temporary Access Pass.

Door op Accept te klikken krijgt de Microsoft Graph module toegang.

Overzicht van rechten

Microsoft Graph toont een lijst met rechten die gebruikt kunnen worden.

Dit lijkt een lange lijst, maar deze rechten horen bij de Microsoft Graph Command Line Tools.

Het script zelf gebruikt alleen:

Authentication Method Policy management

Waarom deze TAP instellingen?

In het script gebruik ik de volgende instellingen.

Default lifetime – 30 minuten

DefaultLifetimeInMinutes = 30

Dit betekent dat een TAP standaard 30 minuten geldig is.

Lang genoeg voor een gebruiker om:

  • de code te ontvangen
  • in te loggen
  • MFA te registreren

Maar kort genoeg om risico te beperken.

Minimum lifetime – 10 minuten

MinimumLifetimeInMinutes = 10

Dit voorkomt dat iemand per ongeluk een TAP maakt die bijna direct verloopt.

Maximum lifetime – 60 minuten

MaximumLifetimeInMinutes = 60

Hiermee voorkom je dat TAP codes uren of dagen geldig blijven.

Een TAP moet tijdelijk blijven.

TAP lengte – 14 tekens

TapLength = 14

Dit geeft een goede balans tussen:

  • veiligheid
  • entropie
  • gebruiksgemak

Eénmalig gebruik

UsableOnce = $true

Dit is een belangrijke beveiligingsmaatregel.

Na gebruik is de TAP direct ongeldig.

Security best practices voor TAP

Een paar praktische adviezen die ik zelf vaak gebruik in tenants.

Gebruik altijd “usable once”

Een TAP moet maar één keer gebruikt kunnen worden.

Dit voorkomt hergebruik van de code.

Houd de geldigheid kort

Aanbevolen waarden:

Default: 30 minuten
Maximum: 60 minuten

Hoe korter de geldigheid, hoe kleiner het risico.

Gebruik Conditional Access

Combineer TAP met:

  • Conditional Access
  • MFA registratie policies
  • Identity Protection

Zo blijft TAP veilig.

Beperk wie TAP mag genereren

Gebruik alleen rollen zoals:

  • Authentication Administrator
  • Privileged Authentication Administrator

Zo voorkom je dat te veel mensen tijdelijke toegang kunnen genereren.

Logging en troubleshooting

Het script schrijft logs naar:

C:\Log

Hier wordt onder andere opgeslagen:

  • script versie
  • gebruiker
  • apparaat
  • IP adres
  • TAP configuratie

Daarnaast wordt het transcript gekopieerd naar:

C:\ProgramData\Microsoft\IntuneManagementExtension\Logs

Hierdoor kun je het script ook gebruiken binnen Intune of automatisering.

Het PowerShell script

Hieronder staat het volledige script dat de TAP-policy configureert.

param (
[switch]$Silent,
[int]$DefaultLifetimeInMinutes = 30,
[int]$MinimumLifetimeInMinutes = 10,
[int]$MaximumLifetimeInMinutes = 60,
[int]$TapLength = 14,
[bool]$UsableOnce = $true
)

<#
.NOTES
===============================================================================
Created on: 2026-03-13
Created by: Vincent van Unen
Organization:
Filename: Set-TAPPolicy-v2.ps1
===============================================================================

.DESCRIPTION
Wijzigt de Temporary Access Pass-configuratie binnen Microsoft Entra ID
via Microsoft Graph. Indien Microsoft Graph nog niet is geïnstalleerd,
wordt deze automatisch geïnstalleerd voor de huidige gebruiker.

.VERSION
1.4.0
#>

#region Script metadata
$ScriptAuthor = "Vincent van Unen"
$ScriptVersion = "1.4.0"
$ScriptChangeDate = "2026-03-13"
$ScriptChangeLog = "Toegevoegd: controle en automatische installatie van Microsoft.Graph, parameterisering van TAP-instellingen"
$ScriptCurrentUser = $env:USERNAME
$ScriptRunningDevice = $env:COMPUTERNAME
$CurrentDate = Get-Date -Format 'yyyy-MM-dd'
$ScriptName = "Set-TAPPolicy-v2"
#endregion Script metadata

#region Paths
$TempPaths = @(
"C:\Temp",
"C:\Tmp",
"C:\Log"
)

foreach ($Path in $TempPaths) {
if (-not (Test-Path -Path $Path)) {
New-Item -ItemType Directory -Path $Path -Force | Out-Null
}
}

$LogDirectory = "C:\Log"
$LogFile = Join-Path $LogDirectory "$ScriptName-$CurrentDate.log"
$TranscriptFile = Join-Path $LogDirectory "$ScriptName-$CurrentDate-Transcript.log"
$IntuneLogPath = "C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"
#endregion Paths

#region Logging
function Write-ToLogFile {
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[ValidateSet("INFO", "WARN", "ERROR", "FATAL", "DEBUG")]
[string]$Level = "INFO",

[Parameter(Mandatory = $true)]
[string]$Message,

[Parameter(Mandatory = $false)]
[string]$FilePath = $LogFile
)

try {
if ([string]::IsNullOrWhiteSpace($Message)) {
Add-Content -Path $FilePath -Value "" -ErrorAction Stop
}
else {
$Date = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss.fff')
Add-Content -Path $FilePath -Value "[$Date] [$Level] $Message" -ErrorAction Stop
}
}
catch {
Write-Warning "Schrijven naar logbestand is mislukt: $($_.Exception.Message)"
}
}
#endregion Logging

#region Helper functions
function Get-PublicIP {
[CmdletBinding()]
param ()

try {
return (Invoke-RestMethod -Uri "https://ifconfig.me/ip" -ErrorAction Stop).Trim()
}
catch {
Write-ToLogFile -Level "WARN" -Message "Publiek IP-adres kon niet worden opgehaald: $($_.Exception.Message)"
return "Onbekend"
}
}

function Get-PrivateIP {
[CmdletBinding()]
param ()

try {
$IpAddress = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction Stop |
Where-Object {
$_.IPAddress -notlike '169.254*' -and
$_.IPAddress -ne '127.0.0.1'
} |
Select-Object -ExpandProperty IPAddress -First 1

if ([string]::IsNullOrWhiteSpace($IpAddress)) {
return "Onbekend"
}

return $IpAddress
}
catch {
Write-ToLogFile -Level "WARN" -Message "Privé IP-adres kon niet worden opgehaald: $($_.Exception.Message)"
return "Onbekend"
}
}

function Install-MicrosoftGraphModule {
[CmdletBinding()]
param ()

try {
$ModuleExists = Get-Module -ListAvailable -Name Microsoft.Graph

if (-not $ModuleExists) {
Write-ToLogFile -Message "Microsoft.Graph module niet gevonden. Installatie wordt gestart."

if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) {
Write-ToLogFile -Message "NuGet package provider niet gevonden. Installatie wordt gestart."
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop
}

$PsGallery = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue
if ($PsGallery -and $PsGallery.InstallationPolicy -ne 'Trusted') {
Write-ToLogFile -Message "PSGallery wordt op Trusted gezet."
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop
}

Install-Module Microsoft.Graph -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop
Write-ToLogFile -Message "Microsoft.Graph module succesvol geïnstalleerd."
}
else {
Write-ToLogFile -Message "Microsoft.Graph module is al aanwezig."
}

Import-Module Microsoft.Graph.Authentication -ErrorAction Stop
Write-ToLogFile -Message "Microsoft.Graph.Authentication module succesvol geladen."
}
catch {
Write-ToLogFile -Level "ERROR" -Message "Installatie of import van Microsoft.Graph is mislukt: $($_.Exception.Message)"
throw
}
}

function Test-TapParameters {
[CmdletBinding()]
param ()

if ($MinimumLifetimeInMinutes -gt $DefaultLifetimeInMinutes) {
throw "MinimumLifetimeInMinutes mag niet groter zijn dan DefaultLifetimeInMinutes."
}

if ($MaximumLifetimeInMinutes -lt $DefaultLifetimeInMinutes) {
throw "MaximumLifetimeInMinutes mag niet kleiner zijn dan DefaultLifetimeInMinutes."
}

if ($TapLength -lt 8 -or $TapLength -gt 48) {
throw "TapLength moet tussen 8 en 48 liggen."
}

if ($MinimumLifetimeInMinutes -lt 10) {
throw "MinimumLifetimeInMinutes moet minimaal 10 zijn."
}
}
#endregion Helper functions

#region Script start
$PublicIP = Get-PublicIP
$PrivateIP = Get-PrivateIP

Write-ToLogFile -Message "Huidige datum = $CurrentDate"
Write-ToLogFile -Message "Script auteur = $ScriptAuthor"
Write-ToLogFile -Message "Script versie = $ScriptVersion"
Write-ToLogFile -Message "Wijzigingsdatum = $ScriptChangeDate"
Write-ToLogFile -Message "Wijzigingslog = $ScriptChangeLog"
Write-ToLogFile -Message "Gebruiker die dit script uitvoert = $ScriptCurrentUser"
Write-ToLogFile -Message "Apparaat waarop dit script draait = $ScriptRunningDevice"
Write-ToLogFile -Message "Publiek IP-adres = $PublicIP"
Write-ToLogFile -Message "Privé IP-adres = $PrivateIP"
Write-ToLogFile -Message "Gewenste TAP-configuratie: DefaultLifetime=$DefaultLifetimeInMinutes, MinimumLifetime=$MinimumLifetimeInMinutes, MaximumLifetime=$MaximumLifetimeInMinutes, TapLength=$TapLength, UsableOnce=$UsableOnce"

try {
Start-Transcript -Path $TranscriptFile -Force | Out-Null
}
catch {
Write-ToLogFile -Level "WARN" -Message "Transcript kon niet worden gestart: $($_.Exception.Message)"
}
#endregion Script start

try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-ToLogFile -Message "TLS 1.2 is ingesteld."

Write-ToLogFile -Message "Valideren van TAP-parameters."
Test-TapParameters
Write-ToLogFile -Message "TAP-parameters zijn geldig."

Write-ToLogFile -Message "Controle op Microsoft.Graph module gestart."
Install-MicrosoftGraphModule

Write-ToLogFile -Message "Verbinding maken met Microsoft Graph."
Connect-MgGraph -Scopes "Policy.ReadWrite.AuthenticationMethod" -ErrorAction Stop | Out-Null

$Context = Get-MgContext
Write-ToLogFile -Message "Verbonden met tenant: $($Context.TenantId)"
Write-ToLogFile -Message "Verbonden met account: $($Context.Account)"

Write-ToLogFile -Message "Huidige TAP-configuratie ophalen."
$TapBefore = Get-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'temporaryAccessPass' `
-ErrorAction Stop

Write-ToLogFile -Message (
"Huidige TAP-configuratie: " +
"State=$($TapBefore.state), " +
"IsUsableOnce=$($TapBefore.isUsableOnce), " +
"Length=$($TapBefore.length), " +
"MinimumLifetime=$($TapBefore.minimumLifetimeInMinutes), " +
"DefaultLifetime=$($TapBefore.defaultLifetimeInMinutes), " +
"MaximumLifetime=$($TapBefore.maximumLifetimeInMinutes)"
)

$Body = @{
"@odata.type" = "#microsoft.graph.temporaryAccessPassAuthenticationMethodConfiguration"
state = "enabled"
isUsableOnce = $UsableOnce
defaultLifetimeInMinutes = $DefaultLifetimeInMinutes
minimumLifetimeInMinutes = $MinimumLifetimeInMinutes
maximumLifetimeInMinutes = $MaximumLifetimeInMinutes
length = $TapLength
}

Write-ToLogFile -Message "Nieuwe TAP-configuratie toepassen."
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'temporaryAccessPass' `
-BodyParameter $Body `
-ErrorAction Stop

Write-ToLogFile -Message "Nieuwe TAP-configuratie succesvol toegepast."

Write-ToLogFile -Message "Nieuwe TAP-configuratie verifiëren."
$TapAfter = Get-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'temporaryAccessPass' `
-ErrorAction Stop

Write-ToLogFile -Message (
"Nieuwe TAP-configuratie: " +
"State=$($TapAfter.state), " +
"IsUsableOnce=$($TapAfter.isUsableOnce), " +
"Length=$($TapAfter.length), " +
"MinimumLifetime=$($TapAfter.minimumLifetimeInMinutes), " +
"DefaultLifetime=$($TapAfter.defaultLifetimeInMinutes), " +
"MaximumLifetime=$($TapAfter.maximumLifetimeInMinutes)"
)

if (-not $Silent) {
Write-Host ""
Write-Host "--- TAP policy na update ---"
$TapAfter |
Select-Object `
state,
isUsableOnce,
length,
minimumLifetimeInMinutes,
defaultLifetimeInMinutes,
maximumLifetimeInMinutes |
Format-Table -AutoSize
Write-Host ""
}
}
catch {
Write-ToLogFile -Level "ERROR" -Message "Er is een fout opgetreden: $($_.Exception.Message)"
Write-Error "Het script is mislukt: $($_.Exception.Message)"
throw
}
finally {
try {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
Write-ToLogFile -Message "Microsoft Graph-verbinding is gesloten."
}
catch {
Write-ToLogFile -Level "WARN" -Message "Microsoft Graph kon niet netjes worden afgesloten."
}

try {
Stop-Transcript | Out-Null
}
catch {
Write-ToLogFile -Level "WARN" -Message "Transcript kon niet worden gestopt."
}

try {
if (Test-Path -Path $IntuneLogPath) {
Copy-Item -Path $TranscriptFile -Destination $IntuneLogPath -Force
Write-ToLogFile -Message "Transcriptbestand gekopieerd naar: $IntuneLogPath"
}
else {
Write-ToLogFile -Level "WARN" -Message "Doelmap voor Intune-logs bestaat niet: $IntuneLogPath"
}
}
catch {
Write-ToLogFile -Level "WARN" -Message "Kopiëren van transcriptbestand is mislukt: $($_.Exception.Message)"
}
}

Wanneer gebruik je TAP?

Een paar situaties waarin TAP ideaal is.

Nieuwe medewerker

Nieuwe gebruiker krijgt TAP om:

  • eerste login te doen
  • MFA te configureren

Nieuwe telefoon

Gebruiker heeft een nieuwe telefoon.

Met TAP kan hij eenvoudig MFA opnieuw instellen.

Recovery scenario

Als MFA volledig stuk is, kan TAP gebruikt worden als veilige tijdelijke toegang.

Conclusie

Temporary Access Pass is een van de meest onderschatte features van Microsoft Entra ID.

Met een goede configuratie kun je:

  • MFA onboarding verbeteren
  • support tickets verminderen
  • recovery eenvoudiger maken
  • veiligheid behouden

Door dit via PowerShell te automatiseren hoef je het maar één keer goed in te richten.

Daarna laat je het script het werk doen.

Precies zoals het hoort.

About the Author

Vincent van Unen

Administrator

Visit Website View All Posts

Post navigation

Previous: Home Assistant – Automation: als infra-bewaker: van “alles draait” naar “hé, wat ligt eruit?”
Next: 🔎 Even snel de Tenant ID van een domein ophalen met PowerShell

Related Stories

ChatGPT Image Mar 13, 2026, 05_39_33 AM
  • Azure
  • Powershell

🔎 Even snel de Tenant ID van een domein ophalen met PowerShell

Vincent van Unen 2026-03-13
ChatGPT Image Mar 11, 2026, 02_16_25 PM
  • Intune
  • Powershell

Powershell – 🔥 Windows Firewall automatisch herstellen met Intune Proactive Remediation

Vincent van Unen 2026-03-11
ChatGPT Image Mar 11, 2026, 01_55_02 PM
  • Intune
  • Powershell

Powershell – 🔐 BitLocker automatisch controleren en inschakelen met PowerShell

Vincent van Unen 2026-03-11

Recent Posts

  • 🔎 Even snel de Tenant ID van een domein ophalen met PowerShell
  • Powershell : Tijdelijke toegang zonder gedoe: Temporary Access Pass automatiseren
  • Home Assistant – Automation: als infra-bewaker: van “alles draait” naar “hé, wat ligt eruit?”
  • Powershell – 🔥 Windows Firewall automatisch herstellen met Intune Proactive Remediation
  • Powershell – 🔐 BitLocker automatisch controleren en inschakelen met PowerShell

Recent Comments

No comments to show.

You May Have Missed

ChatGPT Image Mar 13, 2026, 05_39_33 AM
  • Azure
  • Powershell

🔎 Even snel de Tenant ID van een domein ophalen met PowerShell

Vincent van Unen 2026-03-13
ChatGPT Image Mar 13, 2026, 10_06_00 AM
  • Azure
  • Powershell

Powershell : Tijdelijke toegang zonder gedoe: Temporary Access Pass automatiseren

Vincent van Unen 2026-03-13
ChatGPT Image Mar 12, 2026, 12_37_35 PM
  • Automations

Home Assistant – Automation: als infra-bewaker: van “alles draait” naar “hé, wat ligt eruit?”

Vincent van Unen 2026-03-12
ChatGPT Image Mar 11, 2026, 02_16_25 PM
  • Intune
  • Powershell

Powershell – 🔥 Windows Firewall automatisch herstellen met Intune Proactive Remediation

Vincent van Unen 2026-03-11
  • Algemeen
  • Fotografie
  • Home Assistant
  • Microsoft
  • Azure
  • Powershell
  • Algemeen
  • Fotografie
  • Home Assistant
  • Microsoft
  • Azure
  • Powershell
Copyright © 2026 All rights reserved. | ReviewNews by AF themes.