“WE NEED TO DYNAMICALLY ALLOW CERTAIN PEOPLE access to A SELECT GROUP OF MACHINES ON DEMAND AND WITHOUT INTERVENTION. Just say no to local Admins”
-Almost Everyone
For some reason a lot of people around here like to come up with absurd solutions that involve placing hostnames in a .txt file and having them ingested by some stellar application. What a fantastic idea. I’m not at liberty to change this nonsense, but lets work with what we have. This is a multi-part series in which we need to come up with a solution to reduce our local admins footprint. You know that whole thing where everyone thinks they need to be a Local Admin on “All” the machines? Let’s get automating!
This end-to-end solution will involve a number of platforms. Here’s the overview:
- Power Platform – get the data, and perform some prep
- Azure Runbook – add members to an azure group based off of hostnames (data)
- Intune – Proactive Remediation – Give appropriate access based off of logic.
I’ll make it a point to discuss some alternative tools to accomplish the above because knowing is half the battle. Lets hit the Power Platform first. As stated before we have some .txt files in a folder that contain hostnames. These hostnames should be all actual hostnames but some have incorrect names and some are just offline. I need to go through each file and check validity and uptime and then store the data in one list. Again we have multiple files and multiple hosts within each file
Hostnames are conveniently dropped into the text file with no real delimitator other than a line break. We will use some of our really fancy psudo-parsing tools to digest this and isolate what we are after. In this case it is hostname. So for each item, we are going to log a ping response (Important, because as these are entered manually we have a whole host (No pun intended) or problems. Lets tease out the “No Device found in AD”, “Failures”, and “Success”. If it’s just a bad ping, you will want to create a variable to log that, as PING results in a 1 or 2, not variations. The following displays what this process looks like.
Once we get our data we want to SAVE AS to a location and we name it with the unique time a date. We also want to make sure that someday our storage doesn’t explode with .csv’s, so we will add a trim flow that removes anything > 14 days.
Now that we have a list of hostnames we need do something with them. The next part of this article will focus on a unique part of this solution which is to give our owners of these machines access to drop files on the hosts when need be without requiring them to be a Local Admin or otherwise. Shout out to my big-brained friend Nathanial Adams for recognizing this as a tool to use as a part of this solution and later saved me from hanging myself in PowerShell. Thank goodness for intelligent people. Moving on. Our end goal is to use Intune Proactive Remediation to give the users the minimal access needed.
- Create an Azure group
- Get hostnames the created group
- Use an Azure Hybrid Worker and create a Runbook
Below is the script to periodically pull the .csv file which we created in the first part, connect to Azure, add new devices, and remove the old.
$file = "\\path\path\downtimelist.csv"
$machinelist = Import-Csv -path $file |where Response -notlike "Unlocatable" | select-object machine -Unique
# Get the connection "AzureRunAsConnection"
$connectionName = "AzureRunAsConnection"
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
#Logging in to Azure...
Connect-MgGraph `
-Tenant $servicePrincipalConnection.TenantId `
-AppId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
$AzureADGroupID = 'Group ID'
$AzureADGroupMembers = Get-MgGroupMember -GroupId $AzureADGroupID -All
$AzureADDevices = foreach ($machine in $machinelist)
{
Get-MgDevice -Search "displayname:$($machine.Machine)" -ConsistencyLevel eventual | Select Id,DeviceId,DisplayName,AccountEnabled
}
$DevicesToAdd = $AzureADDevices | Where-Object { $AzureADGroupMembers.Id -notcontains $_.Id }
$DevicesToRemove = $AzureADGroupMembers.Id | Where-Object { $AzureADDevices.Id -notcontains $_ }
$DevicesToAdd | % { New-MgGroupMember -GroupId $AzureADGroupID -DirectoryObjectId $_.Id }
$ref = '$ref'
$DevicesToRemove | % { Invoke-MgGraphRequest -Method Delete -Uri "https://graph.microsoft.com/v1.0/groups/$AzureADGroupID/members/$($_)/$ref" }
In summary, the above Azure Runbook populates our AAD Group with hosts that will be used as a target for our remediation. Moving into our final stage of the solution we need to evaluate each of our devices listed for the following:
- Does the needed folder (path) exist on the machine?
- Does the folder have the correct NTFS permissions?
- Does the share exist?
- Does the specific share permissions exist?
- Does folder shortcut exist on the desktop?
All of these can be easily evaluated and remediated using Intune Proactive Remediation and more importantly, before the end-user is screaming “It’s broken”. I wont go into details as there are plenty of examples of this, but at the end of the day you are evaluating each condition as an IF statement. Start small and test with each condition before expanding.
There you have it. Now, its possible to perform most if not all of this within Power Platform either Desktop or Cloud, but sometimes we gain better understanding of native capabilities by integration and development outside of box.