Directory Cleanup & Addition of Platform Scripts

This commit is contained in:
Andrew Amason
2025-05-14 13:25:48 -04:00
parent 5b9825e6dc
commit 1be4de9e7b
26 changed files with 1595 additions and 90 deletions

View File

@@ -0,0 +1,292 @@
#Get All Windows 10 Intune Managed Devices for the Tenant
function Get-AuthToken {
<#
.SYNOPSIS
This function is used to authenticate with the Graph API REST interface
.DESCRIPTION
The function authenticate with the Graph API Interface with the tenant name
.EXAMPLE
Get-AuthToken
Authenticates you with the Graph API interface
.NOTES
NAME: Get-AuthToken
#>
[cmdletbinding()]
param
(
[Parameter(Mandatory=$true)]
$User
)
$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User
$tenant = $userUpn.Host
Write-Host "Checking for AzureAD module..."
$AadModule = Get-Module -Name "AzureAD" -ListAvailable
if ($AadModule -eq $null) {
Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview"
$AadModule = Get-Module -Name "AzureADPreview" -ListAvailable
}
if ($AadModule -eq $null) {
write-host
write-host "AzureAD Powershell module not installed..." -f Red
write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow
write-host "Script can't continue..." -f Red
write-host
exit
}
# Getting path to ActiveDirectory Assemblies
# If the module count is greater than 1 find the latest version
if($AadModule.count -gt 1){
$Latest_Version = ($AadModule | select version | Sort-Object)[-1]
$aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version }
# Checking if there are multiple versions of the same module found
if($AadModule.count -gt 1){
$aadModule = $AadModule | select -Unique
}
$adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
}
else {
$adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
}
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null
$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547"
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
$resourceAppIdURI = "https://graph.microsoft.com"
$authority = "https://login.microsoftonline.com/$Tenant"
try {
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
# https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx
# Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession
$platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto"
$userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($User, "OptionalDisplayableId")
$authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result
# If the accesstoken is valid then create the authentication header
if($authResult.AccessToken){
# Creating header for Authorization token
$authHeader = @{
'Content-Type'='application/json'
'Authorization'="Bearer " + $authResult.AccessToken
'ExpiresOn'=$authResult.ExpiresOn
}
return $authHeader
}
else {
Write-Host
Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red
Write-Host
break
}
}
catch {
write-host $_.Exception.Message -f Red
write-host $_.Exception.ItemName -f Red
write-host
break
}
}
function Get-Win10IntuneManagedDevice {
<#
.SYNOPSIS
This gets information on Intune managed device
.DESCRIPTION
This gets information on Intune managed device
.EXAMPLE
Get-Win10IntuneManagedDevice
.NOTES
NAME: Get-Win10IntuneManagedDevice
#>
[cmdletbinding()]
param
(
[parameter(Mandatory=$false)]
[ValidateNotNullOrEmpty()]
[string]$deviceName
)
$graphApiVersion = "beta"
try {
if($deviceName){
$Resource = "deviceManagement/managedDevices?`$filter=deviceName eq '$deviceName'"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)"
(Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).value
}
else {
$Resource = "deviceManagement/managedDevices?`$filter=(((deviceType%20eq%20%27desktop%27)%20or%20(deviceType%20eq%20%27windowsRT%27)%20or%20(deviceType%20eq%20%27winEmbedded%27)%20or%20(deviceType%20eq%20%27surfaceHub%27)))"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)"
(Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).value
}
} catch {
$ex = $_.Exception
$errorResponse = $ex.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($errorResponse)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
Write-Host "Response content:`n$responseBody" -f Red
Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
throw "Get-IntuneManagedDevices error"
}
}
function Get-IntuneDevicePrimaryUser {
<#
.SYNOPSIS
This lists the Intune device primary user
.DESCRIPTION
This lists the Intune device primary user
.EXAMPLE
Get-IntuneDevicePrimaryUser
.NOTES
NAME: Get-IntuneDevicePrimaryUser
#>
[cmdletbinding()]
param
(
[Parameter(Mandatory=$true)]
[string] $deviceId
)
$graphApiVersion = "beta"
$Resource = "deviceManagement/managedDevices"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" + "/" + $deviceId + "/users"
try {
$primaryUser = Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get
return $primaryUser.value."id"
} catch {
$ex = $_.Exception
$errorResponse = $ex.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($errorResponse)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
Write-Host "Response content:`n$responseBody" -f Red
Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
throw "Get-IntuneDevicePrimaryUser error"
}
}
#$authtoken = Get-AuthToken -User andrew.amason@carecentrix.com
$Devices = Get-Win10IntuneManagedDevice | where usersLoggedOn -ne $Null
Foreach ($Device in $Devices) {
Write-Host "Device name:" $device."deviceName" -ForegroundColor Cyan
$IntuneDevicePrimaryUser = Get-IntuneDevicePrimaryUser -deviceId $Device.id
#Check if there is a Primary user set on the device already
if ($IntuneDevicePrimaryUser -eq $null) {
Write-Host "No Intune Primary User Id set for Intune Managed Device" $Device."deviceName" -f Red
}
else {
$PrimaryAADUser = Get-AzureADUser -ObjectId $IntuneDevicePrimaryUser
Write-Host "Intune Device Primary User:" $PrimaryAADUser.displayName
}
#Get the objectID of the last logged in user for the device, which is the last object in the list of usersLoggedOn
$LastLoggedInUser = ($Device.usersLoggedOn[-1]).userId
#Using the objectID, get the user from the Microsoft Graph for logging purposes
$User = Get-AzureADUser -ObjectId $LastLoggedInUser
#Check if the current primary user of the device is the same as the last logged in user
if ($IntuneDevicePrimaryUser -notmatch $User.ObjectId) {
#If the user does not match, then set the last logged in user as the new Primary User
$SetIntuneDevicePrimaryUser = Set-IntuneDevicePrimaryUser -IntuneDeviceId $Device.id -userId $User.id
if ($SetIntuneDevicePrimaryUser -eq "") {
Write-Host "User"$User.displayName"set as Primary User for device '$($Device.deviceName)'..." -ForegroundColor Green
}
}
else {
#If the user is the same, then write to host that the primary user is already correct.
Write-Host "The user '$($User.displayName)' is already the Primary User on the device..." -ForegroundColor Yellow
}
Write-Host
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Michael Niehaus
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,20 @@
# RenameComputer
Sample app for renaming a Hybrid Azure AD joined (AD-joined) device after an Autopilot deployment. Note that you will probably want to customize the RenameComputer.ps1 script to add your own naming logic, then build a new RenameComputer.intunewin package by running the "makeapp.cmd" file from a command prompt.
To set up the RenameComputer app in Intune, perform the following steps.
Add the UpdateOS.intunewin app to Intune and specify the following command line:
powershell.exe -noprofile -executionpolicy bypass -file .\RenameComputer.ps1
To "uninstall" the app, the following can be used (for example, to get the app to re-install):
cmd.exe /c del %ProgramData%\Microsoft\RenameComputer\RenameComputer.ps1.tag
Specify the platforms and minimum OS version that you want to support.
For a detection rule, specify the path and file and "File or folder exists" detection method:
%ProgramData%\Microsoft\RenameComputer RenameComputer.ps1.tag
Deploy the app as a required app to an appropriate set of devices.

View File

@@ -0,0 +1,154 @@
<#PSScriptInfo
.VERSION 1.0
.GUID 3b42d8c8-cda5-4411-a623-90d812a8e29e
.AUTHOR Michael Niehaus
.COMPANYNAME Microsoft
.COPYRIGHT
.TAGS
.LICENSEURI
.PROJECTURI
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
Version 1.0: Initial version.
.PRIVATEDATA
#>
<#
.DESCRIPTION
Rename the computer
#>
Param()
# If we are running as a 32-bit process on an x64 system, re-launch as a 64-bit process
if ("$env:PROCESSOR_ARCHITEW6432" -ne "ARM64")
{
if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe")
{
& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy bypass -File "$PSCommandPath"
Exit $lastexitcode
}
}
# Create a tag file just so Intune knows this was installed
if (-not (Test-Path "$($env:ProgramData)\Microsoft\RenameComputer"))
{
Mkdir "$($env:ProgramData)\Microsoft\RenameComputer"
}
Set-Content -Path "$($env:ProgramData)\Microsoft\RenameComputer\RenameComputer.ps1.tag" -Value "Installed"
# Initialization
$dest = "$($env:ProgramData)\Microsoft\RenameComputer"
if (-not (Test-Path $dest))
{
mkdir $dest
}
Start-Transcript "$dest\RenameComputer.log" -Append
# Make sure we are already domain-joined
$goodToGo = $true
$details = Get-ComputerInfo
if (-not $details.CsPartOfDomain)
{
Write-Host "Not part of a domain."
$goodToGo = $false
}
# Make sure we have connectivity
$dcInfo = [ADSI]"LDAP://RootDSE"
if ($dcInfo.dnsHostName -eq $null)
{
Write-Host "No connectivity to the domain."
$goodToGo = $false
}
if ($goodToGo)
{
# Get the new computer name
#get system serial #:
$SystemSerial = Get-WmiObject win32_bios | select Serialnumber
#Ignore original naming Convention
#$newName = Invoke-RestMethod -Method GET -Uri "https://generatename.azurewebsites.net/api/HttpTrigger1?prefix=AD-"
$newName = $SystemSerial.Serialnumber
# Set the computer name
Write-Host "Renaming computer to $($SystemSerial.Serialnumber)"
Rename-Computer -NewName $SystemSerial.Serialnumber
# Remove the scheduled task
Disable-ScheduledTask -TaskName "RenameComputer" -ErrorAction Ignore
Unregister-ScheduledTask -TaskName "RenameComputer" -Confirm:$false -ErrorAction Ignore
Write-Host "Scheduled task unregistered."
# Make sure we reboot if still in ESP/OOBE by reporting a 1641 return code (hard reboot)
if ($details.CsUserName -match "defaultUser")
{
Write-Host "Exiting during ESP/OOBE with return code 1641"
Stop-Transcript
Exit 1641
}
else {
Write-Host "Initiating a restart in 10 minutes"
& shutdown.exe /g /t 600 /f /c "Restarting the computer due to a computer name change. Save your work."
Stop-Transcript
Exit 0
}
}
else
{
# Check to see if already scheduled
$existingTask = Get-ScheduledTask -TaskName "RenameComputer" -ErrorAction SilentlyContinue
if ($existingTask -ne $null)
{
Write-Host "Scheduled task already exists."
Stop-Transcript
Exit 0
}
# Copy myself to a safe place if not already there
if (-not (Test-Path "$dest\RenameComputer.ps1"))
{
Copy-Item $PSCommandPath "$dest\RenameComputer.PS1"
}
# Create the scheduled task action
$action = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-NoProfile -ExecutionPolicy bypass -WindowStyle Hidden -File $dest\RenameComputer.ps1"
# Create the scheduled task trigger
$timespan = New-Timespan -minutes 5
$triggers = @()
$triggers += New-ScheduledTaskTrigger -Daily -At 9am
$triggers += New-ScheduledTaskTrigger -AtLogOn -RandomDelay $timespan
$triggers += New-ScheduledTaskTrigger -AtStartup -RandomDelay $timespan
# Register the scheduled task
Register-ScheduledTask -User SYSTEM -Action $action -Trigger $triggers -TaskName "RenameComputer" -Description "RenameComputer" -Force
Write-Host "Scheduled task created."
}
Stop-Transcript

View File

@@ -0,0 +1 @@
[0609/152259.905:ERROR:registration_protocol_win.cc(106)] CreateFile: The system cannot find the file specified. (0x2)

View File

@@ -0,0 +1 @@
intunewinapputil.exe -c RenameComputer -s RenameComputer.ps1 -o .\ -q

View File

@@ -0,0 +1,67 @@
<#
.SYNOPSIS
Rotates All BitLocker keys for all Windows devices in Intune using Graph API.
.DESCRIPTION
This script connects to Intune via Graph API and rotates the BitLocker keys for all managed Windows devices.
.NOTES
Author: Ugur Koc
GitHub: https://github.com/ugurkocde
Twitter: https://x.com/UgurKocDe
LinkedIn: https://www.linkedin.com/in/ugurkocde/
Version: 1.0
Created: 07/20/2024
Version: 1.1 (07/20/2024)
- Changed Authentication to Connect-MgGraph -Scopes only.
Version: 1.2 (07/20/2024)
- Added pagination.
- Moved the OS Filter to the top, to avoid unnecessary API calls.
.REQUIREMENTS
- PowerShell 5.1 or later
- Microsoft.Graph.Authentication module
.LINK
https://learn.microsoft.com/en-us/graph/api/intune-devices-manageddevice-rotatebitlockerkeys?view=graph-rest-beta
.EXAMPLE
.\rotate_all_bitlocker_keys.ps1
.NOTES
Disclaimer: This script is provided AS IS without warranty of any kind. Use it at your own risk.
#>
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.ReadWrite.All" -NoWelcome
# Get all managed Windows devices from Intune with pagination
$managedDevices = @()
$nextLink = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$select=id,deviceName,operatingSystem&`$filter=operatingSystem eq 'Windows'"
# This loop will get all managed devices from Intune with pagination
while ($nextLink) {
$response = Invoke-MgGraphRequest -Method GET -Uri $nextLink
$managedDevices += $response.value
$nextLink = $response.'@odata.nextLink'
}
foreach ($device in $managedDevices) {
$deviceId = $device.id
$deviceName = $device.deviceName
Write-Host "Processing device: $deviceName" -ForegroundColor Cyan
# Attempt to rotate the BitLocker keys
try {
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices('$deviceId')/rotateBitLockerKeys" -ContentType "application/json"
Write-Host "Successfully rotated BitLocker keys for device $deviceName" -ForegroundColor Green
}
catch {
Write-Host "Failed to rotate BitLocker keys for device $deviceName" -ForegroundColor Red
Write-Host "Error: $_" -ForegroundColor Red
}
}
Write-Host "BitLocker key rotation process completed." -ForegroundColor Cyan