diff --git a/ActiveDirectory/Add-ADUCAttribute.ps1 b/ActiveDirectory/Add-ADUCAttribute.ps1 new file mode 100644 index 0000000..b3a8418 --- /dev/null +++ b/ActiveDirectory/Add-ADUCAttribute.ps1 @@ -0,0 +1,97 @@ +<# +Add additional columns to Active Directory Users and Computers snap-in. + +THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR RESULTS FROM THE USE OF +THIS CODE REMAINS WITH THE USER. + +Author: Aaron Guilmette + aaron.guilmette@microsoft.com +#> + +<# +.SYNOPSIS +Add ability to view additional attributes as columns in Active Directory +Users and Computers MMC Snap-In. + +.DESCRIPTION +Extend the Active Directory Users and Computers MMC Snap-In with +additional attributes. + +.PARAMETER Visibility +Configure whether or not this attribute will be visible by default. + +.PARAMETER ColumnWidth +Determines the width of the new column. Values are -1-255. -1 is Auto. + +.PARAMETER Language +Select language of display specifier to modify. Default is English. + +.PARAMETER NewAttribute +Name of new attribute to add. + +.PARAMETER Title +Column title. If not specified, will use attribute name. + +.EXAMPLE +Add-ADUCAttribute.ps1 -NewAttribute extensionAttribute1 + +.EXAMPLE +Add-ADUCAttribute.ps1 -NewAttribute extensionAttribute1 -Title "Extension Attribute 1" + +.LINK +https://gallery.technet.microsoft.com/Extend-Active-Directory-ccad3d1a +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory=$False,HelpMessage='Column is visible by default in ADUC')] + [ValidateSet("0","1")] + $Visibility = 1, + + [Parameter(Mandatory=$False,HelpMessage='Column width')] + [ValidateRange("-1","255")] + $Width = -1, + + [Parameter(Mandatory=$False,HelpMessage='Language code (US [409] is default)')] + [ValidateSet("401","404","405","406","407","408","409","40B","40C","40D","40E","410","411","412","413","414","415","416","419","41D","41F","804","816","C04","C0A")] + $Language = 409, + + [Parameter(Mandatory=$False,HelpMessage='Column title or description')] + $Title, + + [Parameter(Mandatory=$True,HelpMessage='Attribute to add as column')] + [String]$NewAttribute + ) + +Import-Module ActiveDirectory +$Reserved = 0 + +If (!($Title)) + { + $Title = $NewAttribute + } + +$Config = (Get-ADRootDSE).configurationNamingContext +$ouDisplaySpecifier = Get-ADObject -Identity "CN=organizationalUnit-Display,CN=$Language,CN=DisplaySpecifiers,$Config" -Properties * +$defaultDisplaySpecifier = Get-ADObject -Identity "CN=default-Display,CN=$Language,CN=DisplaySpecifiers,$config" -Properties * + +If ($ouDisplaySpecifier.extraColumns.Count -ge 1) + { + Write-Host -ForegroundColor Cyan "organizationalUnit-Display specifiers already has values. Adding new attribute to existing values." + $extraColumns = $ouDisplaySpecifier.extraColumns + Write-Host -ForegroundColor DarkCyan "Existing contents are: $($extraColumns)" + } +else + { + Write-Host -ForegroundColor Yellow "extraColumns attribute is currently empty. Importing default-Display specifier values." + $extraColumns += $defaultDisplaySpecifier.extraColumns + } + + +$NewAttribute = $NewAttribute + "," + $Title + ",$Visibility,$Width,$Reserved" +$extraColumns += $NewAttribute +Write-Host -ForegroundColor Green "Updating OU Display Specifiers with $($NewAttribute)." +Set-ADObject $ouDisplaySpecifier -Replace @{extraColumns=$extraColumns} \ No newline at end of file diff --git a/ActiveDirectory/ExtendComputerSchema.ps1 b/ActiveDirectory/ExtendComputerSchema.ps1 new file mode 100644 index 0000000..bd1f3ec --- /dev/null +++ b/ActiveDirectory/ExtendComputerSchema.ps1 @@ -0,0 +1,147 @@ +<# +Extend User Schema +Script: ExtendComputerSchema.ps1 +Reference URL: https://www.linkedin.com/pulse/using-powershell-extend-user-schema-active-directory-james-sargent/ + + +Author: James Sargent +Created: 2019/03/19 + +Summary +This script creates AD Attributes for computers; after running the script successfully, you should see additional attributes assigned to the computer. +Always test your schema changes in a test environment before making any changes. + +Requirements +PowerShell 4.0 or higher +AD PowerShell Modules (RSAT) + + +CSV Not Used -CSV File configuration +CSV Not Used -Name,oMSyntax,AttributeSyntax,isSingleValued,Description,Indexed + +Custom-LastLoggedOnUser – Last logged on user +Custom-LastLoggedOnUserDate – Last time the user logged on +Custom-HardwareVendor – Hardware Manufacturer +Custom-HardwareModel – Hardware Model +Custom-SerialNumber – for populating the serial number of each computer +Custom-SNID - Acer specific SNID if available + +Name: Should not have any characters other than letters or numbers +oMSyntax and AttributeSyntax: These settings can be found here https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/7cda533e-d7a4-4aec-a517-91d02ff4a1aa +isSingleValued: True or False +Description: Keep it short, I avoid commas in mine +Indexed: Yes or No +#> +$dryRun = $true # A dry run will not attempt to Update the schema and just show the command results. Recommend set to $false after testing. + + # Self-elevate the script if required +if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { + Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`""; + exit; +} + +# Add self to Schema Admins +try { + Add-ADGroupMember -Identity "Schema Admins" -members $env:UserName + Write-Host "$env:UserName added to Schema Admins groups" + } catch { + Write-Host "$env:UserName already in Admins groups or an error occured" + Write-Host $_ +} + +Stop-Service -DisplayName 'Active Directory Domain Services' -Force +Start-Service -DisplayName 'Active Directory Domain Services' + +# Set the path and file name to your import file +#$arrAttributes = Import-CSV "c:\Scriptes\NewAttributes.csv" +# hard coded Attributeds +# Name,oMSyntax,AttributeSyntax,isSingleValued,Description,Indexed +$arrAttributes = @() +$arrAttributes = @( +("Custom-LastLoggedOnUser","64","2.5.5.12","TRUE","Last logged on user","YES"), +("Custom-LastLoggedOnUserDate","64","2.5.5.12","TRUE","Last time the user logged on","YES"), +("Custom-HardwareVendor","64","2.5.5.12","TRUE","Hardware Manufacturer","YES"), +("Custom-HardwareModel","64","2.5.5.12","TRUE","Hardware Model","YES"), +("Custom-SerialNumber","64","2.5.5.12","TRUE","For populating the serial number of each computer","YES"), +("Custom-SNID","64","2.5.5.12","TRUE","Acer specific SNID if available","YES") +) + + +# DO NOT EDIT BELOW THIS LINE +# ---------------------------------------------------------------------- + +function funGenOID +{ +<# Orignal code for generating an OID +https://gallery.technet.microsoft.com/scriptcenter/Generate-an-Object-4c9be66a + +Generates an object identifier (OID) using a GUID and the OID prefix 1.2.840.113556.1.8000.2554. This is a PowerShell equivalent of VBScript published here: http://gallery.technet.microsoft.com/scriptcenter/56b78004-40d0-41cf-b95e-6e795b2e8a06/ +#> + +$Prefix="1.2.840.113556.1.8000.2554" +$GUID=[System.Guid]::NewGuid().ToString() +$Parts=@() +$Parts+=[UInt64]::Parse($guid.SubString(0,4),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(4,4),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(9,4),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(14,4),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(19,4),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(24,6),"AllowHexSpecifier") +$Parts+=[UInt64]::Parse($guid.SubString(30,6),"AllowHexSpecifier") +$OID=[String]::Format("{0}.{1}.{2}.{3}.{4}.{5}.{6}.{7}",$prefix,$Parts[0],$Parts[1],$Parts[2],$Parts[3],$Parts[4],$Parts[5],$Parts[6]) +Return $oid +} + +# Set Schema Path +$schemaPath = (Get-ADRootDSE).schemaNamingContext + +# Get Computer Schema Object +$ComputerSchema = get-adobject -SearchBase $schemapath -Filter 'name -eq "computer"' + +ForEach ($tmpAttrib in $arrAttributes) +{ +# Build OtherAttributes +$Attribute = @{ + lDAPDisplayName = $tmpAttrib[0]; + attributeId = funGenOID + oMSyntax = $tmpAttrib[1]; + attributeSyntax = $($tmpAttrib[2]); + isSingleValued = if ($($tmpAttrib[3]).isSingleValued -like "*true*") {$True} else {$false}; + adminDescription = $($tmpAttrib[4]); + searchflags = if ($($tmpAttrib[5]) -like "yes") {1} else {0} + } + +if ($dryRun) { + Write-Host "******" + Write-Host "TEST Build Object" + Write-Host "******" + Write-Host "New-ADObject -Name $($tmpAttrib[0]) -Type attributeSchema -Path $schemaPath -OtherAttributes $Attribute" + Write-Host "******" + Write-Host "Test Attribulets" + $Attribute | Select -expand $ExternalConnectionSettings + Write-Host "******" + Write-Host "Test Add to User Schema Command" + Write-Host "$ComputerSchema | Set-ADObject -Add @{mayContain = $($tmpAttrib[0])}" + Write-Host "******" + + } else { + +try { + New-ADObject -Name $($tmpAttrib[0]) -Type attributeSchema -Path $schemaPath -OtherAttributes $Attribute + try { + $ComputerSchema | Set-ADObject -Add @{mayContain = $($tmpAttrib[0])} + } catch { + Write-Host "An error occurred:" + Write-Host $_ + exit 0 + } + } catch { + Write-Host "An error occurred:" + Write-Host $_ + exit 0 +} + + Write-host "Attributes created" + + } +} diff --git a/ActiveDirectory/Set-ComputerCustomAttributes.ps1 b/ActiveDirectory/Set-ComputerCustomAttributes.ps1 index 91ccf71..4493d9c 100644 --- a/ActiveDirectory/Set-ComputerCustomAttributes.ps1 +++ b/ActiveDirectory/Set-ComputerCustomAttributes.ps1 @@ -4,7 +4,7 @@ # Auther: eshoemaker@lockstepgroup.com # Last Updated: Q2 2017 # Sets custom Active Directory attributes -# Reference URL: +# Reference URL: https://lockstepgroup.com/blog/fun-with-ad-custom-attributes/ # ################################################################################################### @@ -61,11 +61,33 @@ $ComputerName=$env:COMPUTERNAME Write-Log "Computer Name = $ComputerName" Write-Log "GATHERING LAST LOGGED ON USER INFO" -$LogonType=2 #Interactive Logon $30Days=(Get-Date).adddays(-30) -$LogonEvent=(Get-EventLog -LogName Security -InstanceId 4624 -After $30Days | Where {$_.ReplacementStrings[8] -eq $LogonType -and $_.ReplacementStrings[6] -ne "Window Manager"})[0] -$LoggedOnUser=($LogonEvent.ReplacementStrings[6])+'\'+($LogonEvent.ReplacementStrings[5]) -$Date=$LogonEvent.TimeGenerated + +function LogOnSuccess { + Try { + $Events = Get-WinEvent -MaxEvents 1 -LogName "Security" -FilterXPath "*[System[(EventID='4624')] and EventData[Data[@Name='LogonType'] and (Data='2' or Data='10' or Data='11')]` + and EventData[Data[@Name='TargetDomainName']!='Window Manager'] and EventData[Data[@Name='TargetDomainName']!='Font Driver Host']and EventData[Data[@Name='TargetUserName']!='Administrator'] and EventData[Data[@Name='TargetUserName']!='SYSTEM'] and EventData[Data[@Name='TargetUserName']!='SYSTEM'] and EventData[Data[@Name='TargetUserName']!='LOCAL SERVICE'] and EventData[Data[@Name='TargetUserName']!='SCCM_Svc'] and EventData[Data[@Name='TargetUserName']!='NETWORK SERVICE']]" -ErrorAction Stop + ForEach ($Event in $Events) { + $eventXML = [xml]$Event.ToXml() + Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name "TimeCreate" -Value $Event.TimeCreated + FOREACH ($j in $eventXML.Event.System.ChildNodes) { + Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name $j.ToString() -Value $eventXML.Event.System.($j.ToString()) + } + For ($i=0; $i -lt $eventXML.Event.EventData.Data.Count; $i++) { + Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name $eventXML.Event.EventData.Data[$i].name -Value $eventXML.Event.EventData.Data[$i].'#text' + } + } + $global:LoggedOnUser=($Events | select -expand TargetUserName) + $global:LoggedOnDomain=($Events | select -expand TargetDomainName) + $global:Date=($Events | select -expand TimeCreate) + $global:LoggedOnUser=($global:LoggedOnDomain)+'\'+($global:LoggedOnUser) + } + Catch { return 'Result: Null'} + } + + + +LogOnSuccess Write-Log "Last Logged On User = $LoggedOnUser"