Add logon script to set computer ManagedBy attribute

This commit is contained in:
2026-04-21 14:47:21 +10:00
parent 82ebcdac9d
commit 63e3de4581
+134
View File
@@ -0,0 +1,134 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Sets the Active Directory computer object's "Managed By" attribute to the currently logged-in user.
.DESCRIPTION
Designed to run as a GPO User Logon Script. On each login, it resolves the current
user and computer in AD, then stamps the user's Distinguished Name into the computer
object's "managedBy" attribute.
PREREQUISITES:
- The RSAT ActiveDirectory PowerShell module must be installed on client machines,
OR the script can fall back to ADSI/DirectorySearcher (no module needed).
- AD permissions must be delegated so that Authenticated Users (or Domain Users)
can WRITE the "managedBy" attribute on Computer objects in the relevant OU(s).
See README.md for delegation instructions.
.NOTES
Deploy via: GPO > User Configuration > Policies > Windows Settings > Scripts > Logon
Filename: Set-ComputerManagedBy.ps1
#>
# ── Configuration ────────────────────────────────────────────────────────────
$LogFile = "$env:TEMP\Set-ComputerManagedBy.log"
$MaxLogSizeKB = 256
# ── Logging helper ───────────────────────────────────────────────────────────
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$entry = "[$timestamp] [$Level] $Message"
# Rotate log if oversized
if ((Test-Path $LogFile) -and ((Get-Item $LogFile).Length / 1KB -gt $MaxLogSizeKB)) {
Remove-Item $LogFile -Force -ErrorAction SilentlyContinue
}
Add-Content -Path $LogFile -Value $entry -ErrorAction SilentlyContinue
}
# ── Gather environment ──────────────────────────────────────────────────────
$currentUser = $env:USERNAME
$computerName = $env:COMPUTERNAME
$userDomain = $env:USERDOMAIN
Write-Log "Script started. User=$userDomain\$currentUser, Computer=$computerName"
# ── Skip if local/non-domain login ──────────────────────────────────────────
if ($userDomain -eq $computerName) {
Write-Log "Local login detected (domain = computername). Skipping." "WARN"
exit 0
}
# ── Try AD module first, fall back to ADSI ──────────────────────────────────
$useADModule = $false
try {
Import-Module ActiveDirectory -ErrorAction Stop
$useADModule = $true
Write-Log "Using ActiveDirectory PowerShell module."
} catch {
Write-Log "AD module not available. Falling back to ADSI/DirectorySearcher." "WARN"
}
try {
if ($useADModule) {
# ── AD Module path ──────────────────────────────────────────────────
$userObj = Get-ADUser -Identity $currentUser -ErrorAction Stop
$computerObj = Get-ADComputer -Identity $computerName -ErrorAction Stop
$currentManagedBy = (Get-ADComputer -Identity $computerName -Properties managedBy).managedBy
if ($currentManagedBy -eq $userObj.DistinguishedName) {
Write-Log "ManagedBy already set to $currentUser. No change needed."
exit 0
}
Set-ADComputer -Identity $computerName -ManagedBy $userObj.DistinguishedName -ErrorAction Stop
Write-Log "SUCCESS: Set ManagedBy on '$computerName' to '$($userObj.DistinguishedName)'"
} else {
# ── ADSI fallback (no module required) ──────────────────────────────
$rootDSE = [ADSI]"LDAP://RootDSE"
$domainDN = $rootDSE.defaultNamingContext
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.SearchRoot = [ADSI]"LDAP://$domainDN"
# Find the user DN
$searcher.Filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=$currentUser))"
$searcher.PropertiesToLoad.Add("distinguishedName") | Out-Null
$userResult = $searcher.FindOne()
if (-not $userResult) {
Write-Log "Could not find user '$currentUser' in AD." "ERROR"
exit 1
}
$userDN = $userResult.Properties["distinguishedname"][0]
# Find the computer DN
$searcher.Filter = "(&(objectCategory=computer)(sAMAccountName=$computerName$))"
$searcher.PropertiesToLoad.Clear()
$searcher.PropertiesToLoad.Add("distinguishedName") | Out-Null
$searcher.PropertiesToLoad.Add("managedBy") | Out-Null
$computerResult = $searcher.FindOne()
if (-not $computerResult) {
Write-Log "Could not find computer '$computerName' in AD." "ERROR"
exit 1
}
$computerDN = $computerResult.Properties["distinguishedname"][0]
# Check current value
$currentManagedBy = $null
if ($computerResult.Properties["managedby"].Count -gt 0) {
$currentManagedBy = $computerResult.Properties["managedby"][0]
}
if ($currentManagedBy -eq $userDN) {
Write-Log "ManagedBy already set to $currentUser. No change needed."
exit 0
}
# Set the attribute via ADSI
$computerEntry = [ADSI]"LDAP://$computerDN"
$computerEntry.Put("managedBy", $userDN)
$computerEntry.SetInfo()
Write-Log "SUCCESS: Set ManagedBy on '$computerName' to '$userDN'"
}
} catch {
Write-Log "FAILED to set ManagedBy: $($_.Exception.Message)" "ERROR"
exit 1
}
exit 0