Install-Module PSMDE
This module is optimized for unattended use, so you need to provide a service principal to authenticate against the MDE API. The detailed process to create a service principal with the correct roles is explained here.
You can use the helper function New-MdeServicePrincipal
to create a app registration with the needed permissions:
New-MdeServicePrincipal
uses your current Azure session. If there is no current Azure context (verify with Get-AzContext
), execution will fail. This way you can use it e.g. with the Azure Login Github Action or your current logged in Azure session on you computer.
New-MdeServicePrincipal
Name Value
---- -----
servicePrincipalSecret
servicePrincipalId 12345678-1234-1234-1234-123456789012
servicePrincipalName PSMDE
servicePrincipalTenantId 12345678-1234-1234-1234-123456789012
servicePrincipalApplicationId 12345678-1234-1234-1234-123456789012
servicePrincipalPermissionsUrl https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnA
servicePrincipalSecretExpiration
To also create a secret and add it to the current session credentials automatically, specify the -initialize
parameter.
New-MdeServicePrincipal -initialize
Name Value
---- -----
servicePrincipalSecret abc123
servicePrincipalId 12345678-1234-1234-1234-123456789012
servicePrincipalName PSMDE
servicePrincipalTenantId 12345678-1234-1234-1234-123456789012
servicePrincipalApplicationId 12345678-1234-1234-1234-123456789012
servicePrincipalPermissionsUrl https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnA
servicePrincipalSecretExpiration 10/18/2022 14:20:02
New-AzADAppCredential
.
By default, the New-MdeServicePrincipal
adds all available Read.All
or Read
application permission. If you need to use delegated permissions, use the -delegated
parameter.
To also add permissions for write operations, add the -permissions 'readwrite'
parameter.
After the creation, New-MdeServicePrincipal
will automatically open a browser with the service principals API page to grant permissions. If you don't want this, add the -dontOpenGrantUrl
parameter, but don't forget to grant you service principal permissions before using it.
After you created the service principal or used the New-MdeServicePrincipal
function, you need to add the credentials to the current session to authenticate and refresh the token if necessary (unless you used New-MdeServicePrincipal -initialize
). To initialize or update the session authentication information, use the Set-MdeAuthorizationInfo
function.
Set-MdeAuthorizationInfo -tenantId '00000000-0000-0000-0000-000000000000' -appId '00000000-0000-0000-0000-000000000000' -appSecret 'APP_SECRET'
If you added new scopes or want to manually refresh the token before expiration, use the Clear-MdeAuthorizationInfo
function and add the credentials again with Set-MdeAuthorizationInfo
.
Currently, it's not supported to authenticate via environment variables, this is planned for a future release.
The module will verify the expiration of the current token on every request and will acquire a new one as soon as the existing one has less than 5 minutes life time left. To manually initialize a token refresh, e.g. when adjusting the permission roles, execute Clear-MdeAuthorizationInfo
and set it again with Set-MdeAuthorizationInfo -tenantId '00000000-0000-0000-0000-000000000000' -appId '00000000-0000-0000-0000-000000000000' -appSecret 'APP_SECRET'
.
You can alway get the current roles of your active token using the Get-MdeAuthorizationInfo
function.
To verify the current roles of the active token, execute ``
This will return a object with a tokenExpire
and a `roles` field:
Name Value
---- -----
tokenExpired False
roles { Url.Read.All, Ip.Read.All, Ti.Read.All, User.Read.All }
Each function will check, if the current token roles include at least one of the roles needed for the respective function. To get the needed roles for a specific function, you can use the Get-MdeRoles -functionName 'Add-MdeMachineTag'
function.
You can find help for all available functions in the wiki or by using the PowerShell integrated help. These section provides an overview of the available functions and some examples for common MDE scenarios (contributions welcome).
Function list
- Add-MdeMachineTag
- Clear-MdeAuthorizationInfo
- Disable-MdeMachineCodeExecutionRestriction
- Disable-MdeMachineIsolation
- Enable-MdeMachineCodeExecutionRestriction
- Enable-MdeMachineIsolation
- Get-MdeAuthorizationInfo
- Get-MdeBaselineComplianceAssessmentByMachine
- Get-MdeBaselineComplianceAssessmentExport
- Get-MdeBaselineConfiguration
- Get-MdeBaselineProfile
- Get-MdeConfigurationScore
- Get-MdeExposureScore
- Get-MdeExposureScoreByMachineGroups
- Get-MdeLibraryFiles
- Get-MdeLiveResponseResult
- Get-MdeMachine
- Get-MdeMachineAction
- Get-MdeMachineAlerts
- Get-MdeMachineByFilter
- Get-MdeMachineByIp
- Get-MdeMachineByTag
- Get-MdeMachineInvestigationPackage
- Get-MdeMachineInvestigationPackageUri
- Get-MdeMachineLogonUsers
- Get-MdeMachineMissingKbs
- Get-MdeMachineRecommendations
- Get-MdeMachineSoftware
- Get-MdeMachineVulnerabilities
- Get-MdeRecommendation
- Get-MdeRecommendationMachines
- Get-MdeRecommendationSoftware
- Get-MdeRecommendationVulnerabilities
- Get-MdeRemediationTask
- Get-MdeRemediationTaskMachines
- Get-MdeRoles
- Get-MdeSoftware
- Get-MdeSoftwareByFilter
- Get-MdeSoftwareDistribution
- Get-MdeSoftwareMachineReferences
- Get-MdeSoftwareMissingKbs
- Get-MdeSoftwareVulnerability
- Get-MdeUserAlerts
- Get-MdeUserMachines
- Get-MdeVulnerability
- Get-MdeVulnerabilityByMachine
- Get-MdeVulnerabilityMachinesByVulnerability
- Invoke-MdeMachineAntivirusScan
- Invoke-MdeMachineLiveResponse
- New-MdeServicePrincipal
- Remove-MdeMachine
- Remove-MdeMachineTag
- Set-MdeAuthorizationInfo
- Stop-MdeMachineAction
- Stop-MdeMachineFileExecution
- Update-MdeMachine
$machines = Get-MdeMachine
$mdeMachines = $machines | Where-Object { @('WindowsServer2022', 'WindowsServer2019', 'WindowsServer2016', 'WindowsServer2012R2', 'WindowsServer2008R2') -contains $_.osPlatform } | Select-Object -Property *, @{Name = 'computerName'; Expression = { $_.computerDnsName.split('.')[0] } }
$tag = 'monitoring-onboarded'
$machines = Get-MdeMachines
$fitleredMachines = $machines | Where-Object { $_.computerDnsName.endsWith('.mydomain.local') } | Where-Object { $_.healthStatus -eq 'Active' }
$fitleredMachines | Add-MdeMachineTag -tag $tag
See Contributing Guide.
Made with ❤️
Published under MIT License.