Pages

tirsdag 1. januar 2013

PowerShell: Function to set AD Permission

I wanted to be able to set servicePrincipalName with a PowerShell function. I could not find any function for it, so I created one (Requires PowerShell 3.0):
Function Set-ADPermission {
<#
    .SYNOPSIS
        Add permission for a user or group in ActiveDirectory
    .SYNTAX
        Set-ADPermission
          -Identity <String>
          -PropertyName <String>
          -Target <String>
          -Read
          -Write
    .EXAMPLE
        To give the user svcSQLDbEngine Write permission on property
        servicePrincipalName for himself:
        Set-ADPermission
          -Identity "CONTOSO\svcSQLDbEngine"
          -PropertyName "servicePrincipalName"
          -Target "LDAP://CN=svcSQLDbEngine,OU=ServiceAccounts,DC=contoso,DC=com"
          -Write
    .REQUIREMENTS
        The right to change persmissions in AD
    .OUTPUT
        DirectoryServices.ActiveDirectoryAccessRule
#>
    param(
        [Security.Principal.NTAccount]$Identity,
        [string]$PropertyName,
        [adsi]$Target,
        [switch]$Write,
        [switch]$Read
    )
    If(!$Write -and !$Read){Throw "You must specify either -Write or -Read or both"}
    # Retrieve LDAP Root
    $rootDSE = [adsi]"LDAP://RootDSE"
    # Retrieve Schema Naming Context
    $schemaNC = $rootDSE.Properties["schemaNamingContext"][0]
    # Create DirectorySearcher object
    $ADSearcher = New-Object DirectoryServices.DirectorySearcher
    # Filter on the LDAPDisplayName attribute
    $ADSearcher.Filter = "(&(LDAPDisplayName=$PropertyName))"
    # Search in the Schema
    $ADSearcher.SearchRoot = "LDAP://$schemaNC"
    # Return only one result
    $schemaObj = $ADSearcher.FindOne()
    # Check that we got it
    If(!$schemaObj){Throw "Unable to find $PropertyName in Schema"}
    # Retrieve the GUID of the Attribute Schema
    $schemaIDGUID=@("")
    $schemaIDGUID[0]=$schemaObj.Properties["schemaidguid"][0]
    $oGUID = New-Object GUID $schemaIDGUID
    # Check that we got it
    If(!$oGUID){Throw "Unable to find GUID for $PropertyName in Schema"}
    # Determine the Access Rule
    If($Write -and $Read){$Rights="ReadProperty, WriteProperty"}
    ElseIf($Read){$Rights="ReadProperty"}
    ElseIf($Write){$Rights="WriteProperty"}
    $SecArgs = $Identity,[DirectoryServices.ActiveDirectoryRights]$Rights,"Allow",$oGUID,"None"
    $Rule = New-Object DirectoryServices.ActiveDirectoryAccessRule $SecArgs
    # Check that we got it
    If(!$Rule) {Throw "Unable to build AccessRule for $PropertyName in Schema"}
    # Add the AccessRule to the Object and Commit
    $Target.ObjectSecurity.AddAccessRule($Rule)
    $Target.CommitChanges()
    # Return the AccessRule
    Return $Rule
}