Skip to main content

Automation

Clean up stale Azure AD devices

If you are using Azure AD and the time passes you’ll have a lot of old device entries. If you enable the automatic device cleanup rule in Microsoft Intune the device is only removed within MDM and the Azure AD entry still exists. Intune device cleanup rule For this reason I created a tiny PowerShell snippet to create a report with all devices which didn’t contact your Azure AD tenant since the treshold date specified. If you confirm the operation you can also delete all affected devices. Please be careful when running the script because when removing a device from Azure AD the stored Bitlocker recovery keys are also removed. I can recommend Roger Zander’s Azure table-based Bitlocker recovery key solution.

Set Office 365 UsageLocation property with Azure automation

If you want to assign Microsoft licenses to your Azure AD users e.g. Microsoft 365 E3 licenses you can do this with group based licensing as described here. The problem is that even with group based licensing the UsageLocation property for each user must be set individually. Update: 13.01.2019: Since group based licensing is GA the tenant location is used if no UsageLocation is set on a user object. Use this guide if you want to manually assign licenses or override the tenant settings if you need to configure different UsageLocations. Possible bulk and automation solutions # You can achieve this with the following options: “Manual” trough Azure or Office 365 portal PowerShell (must be triggered manually or through scheduled task) Azure AD Connect synchronisation (UsageLocation populated in on prem AD) Azure automation with PowerShell runbook as in this post 🙂 Azure automation sounds expensive? # Fortunately Azure automation offers 500 minutes of script runtime for free. Find more details under Automation pricing. Just to give you an idea: If the executed script has an average runtime of 1 minute you could run it (500 minutes / (30 calendear days / 1 minute script runtime)) = 16x per day. Each month. For free.

PowerShell Script Test Open TCP Ports

Recently I was troubleshooting ADFS connection issues when I discovered a nice little Cmdlet called “Test-NetConnection”. With this Cmdelet you can verify TCP connectivity, in my case from a client to the ADFS server. The Test-NetConnection cmdlet displays diagnostic information for a connection. It supports ping test, TCP test, route tracing, and route selection diagnostics. Depending on the input parameters, the output can include the DNS lookup results, a list of IP interfaces, IPsec rules, route/source address selection results, and/or confirmation of connection establishment. Find a full documentation on the Microsoft Docs Page. About the script # With this Script you are able to specify server names and port numbers to check in a CSV File. The Script generates an CSV output file as a report. You can use this script for troubleshooting or engineering purposes to verify if TCP ports are opened. Simply add the hostname and TCP port to the “CheckList.csv” and the script checks the specified servers and ports. The script will generate an output file for the same path containing the suffix “Report_” with the test results. CheckList.csv: Report_CheckList.csv generated after script execution:

PowerShell Function Validate Object Properties Using ValidateScript

 Recently I was working on a PowerShell script with many custom functions. When I started to use PowerShell custom objects I wanted to be able to pass them to a function. So I faced the challenge of validating my object for all required properties and came up with this solution, using the ValidateScript block to test the object: Customizing the ValidateScript # As you can see I use a ValidateScript for the parameter validation to test the object for the required properties. The properties can be specified in an array: $requiredProperties=@("Property1","Property2","Property3", "Property4") When we call the Function with an appropriate object: $config= [PSCUSTOMOBJECT]@{ property1= "Value"; property2= "Value"; property3= "Value"; property4= "Value"; } We receive the following output: PS H:\> New-Example -InputObject $config Succesfully passed ValidateScript Result # If we remove one or more properties from our custom object, an error is thrown: PS H:\> $config= [PSCUSTOMOBJECT]@{ property1= "Value"; property2= "Value"; property3= "Value"; } New-Example -InputObject $config New-Example : Cannot validate argument on parameter 'InputObject'. Property: 'Property4' missing At line:10 char:26 + New-Example -InputObject $config + ~~~~~~~ + CategoryInfo : InvalidData: (:) [New-Example], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,New-Example If you want to go a step further you could extend the ValidateScript to… Prevent passing properties with a NULL or empty value # $_.PSObject.Properties | ForEach-Object { if (([string]::IsNullOrEmpty($_.Value))){ Throw [System.Management.Automation.ValidationMetadataException] "Property '$($_.Name)' has either a NULL or empty value" } } If we call our function again with the added IsNullOrEmpty validation NULL or emtpy values throw an exception: