Представьте, что половина ваших пользователей – локальные администраторы на своих машинах. Довольно часто они переустанавливают ОС и просят службу поддержки ввести их компьютеры заново в корпоративный домен Active Directory. Обычно, у нас есть два способа помочь им в этой ситуации: или подойти к рабочему месту пользователя и использовать свои учётные данные для ввода в домен, или пересоздать компьютерный аккаунт, одновременно делегировав им право ввода компьютера в домен. В первом случае, сотруднику службы поддержки приходится ногами идти к рабочему месту пользователя, что может быть довольно выматывающе, особенно для отдалённых локаций. Во втором же, членство компьютера в группах скорее всего будет утеряно и его потребуется восстанавливать вручную.
Возможно ли сократить затраты времени и сил, необходимых на решение таких задач? Да, конечно!
Всё, что нам нужно, это представить пользователю следующие разрешения на учётную запись его компьютера:
- Validated write to DNS host name
- Validated write to service principal name
- List the children of an object
- Read
- Read security information
- List the object access
- Control access right
- Delete an object and all of its children
- Delete
- Write to the following properties:
- sAMAccountName
- displayName
- description
- Logon Information
- Account Restrictions
Пользователь с этими разрешениями сможет ввести свой компьютер в домен AD самостоятельно, без помощи со стороны службы поддержки.
Я сделал небольшой PowerShell-сценарий, чтобы помочь вам в выдаче таких разрешений. Пожалуйста обратимость к его секции помощи (можете использовать командлет Get-Help) за информацией о синтаксисе и примерами использования.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
<# MIT License Copyright (c) 2016 Kirill Nikolaev 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. #> #Requires -Version 3.0 #Requires -Modules ActiveDirectory <# .SYNOPSIS Allows a user to join their computer into Active Directory domain. .DESCRIPTION Allows a user to join their computer into Active Directory domain w/o assistance of Service Desk engineer if the computer account is already pre-created. After executing that script a user can reinstall OS multiple times and still be able to join the machine into domain, while computer name will stay the same. Right now the script works only for the domain where an account running the script resides. .PARAMETER ComputerName sAMAccountName of a computer. .PARAMETER UserName sAMAccountName of a user. .PARAMETER ComputerDomain FQDN of an AD domain where target computer is located. .PARAMETER UserDomain FQDN of an AD domain where target user is located. .EXAMPLE .\Allow-ADDomainJoin.ps1 -UserName ExampleUser -ComputerName ExampleComputer .NOTES NAME: Allow-ADDomainJoin AUTHOR: Kirill Nikolaev LASTEDIT: 03/11/2016 10:02:10 KEYWORDS: Active Directory, ADDS, self-service, service desk, workstations, end-users .LINK https://exchange12rocks.org/2016/03/14/how-to-allow-users-to-join-their-computers-into-ad-domain/ #> Param( [Parameter(Mandatory, HelpMessage='sAMAccount name of a computer account at which you like to delegate domain-joining permissions')] [string]$ComputerName, [Parameter(Mandatory, HelpMessage='sAMAccount name of a user account to which you like to delegate domain-joining permissions')] [string]$UserName, [string]$ComputerDomain = 'example.com', [string]$UserDomain = 'example.com' ) $ErrorActionPreference = 'Stop' Import-Module -Name ActiveDirectory [string]$ComputerWDC = (Get-ADDomainController -DomainName $ComputerDomain -Discover -Writable -NextClosestSite).HostName [string]$UserWDC = (Get-ADDomainController -DomainName $UserDomain -Discover -Writable -NextClosestSite).HostName [string]$ComputerDomainNB = (Get-ADDomain -Identity $ComputerDomain).NetBIOSName Try { $ADObject = Get-ADComputer -Identity $ComputerName -Server $ComputerWDC } Catch { Write-Error -Message ("Cannot get computer {0} from AD DS @ {1}:`r`n{2}`r`n{3}" -f $ComputerName, $ComputerWDC, $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { $null = New-PSDrive -Name $ComputerDomainNB -Root '' -PSProvider ActiveDirectory -Server $ComputerWDC } Catch { Write-Error -Message ("Cannot create new PSDrive for {0} AD domain @ {1}:`r`n{2}`r`n{3}" -f $ComputerDomain, $ComputerWDC, $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { #TODO: Get-Acl desn't support ShouldProcess $DACL = Get-Acl -Path ('{0}:\{1}' -f $ComputerDomainNB, $ADObject.DistinguishedName) } Catch { Write-Error -Message ("Cannot get DACL for object {0} @ {1}:`r`n{2}`r`n{3}" -f $ADObject.DistinguishedName, $ComputerWDC, $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { $UserSID = (Get-ADUser -Identity $UserName -Properties SID -Server $UserWDC).SID } Catch { Write-Error -Message ("Cannot get user {0} from AD DS @ {1}:`r`n{2}`r`n{3}" -f $UserName, $UserWDC, $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { $ACEs = @() } Catch { Write-Error -Message ("Cannot initialize empty ACEs object:`r`n{0}`r`n{1}" -f $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'197076', 'Allow', [GUID]'00000000-0000-0000-0000-000000000000', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'WriteProperty', 'Allow', [GUID]'3e0abfd0-126a-11d0-a060-00aa006c33ed', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'WriteProperty', 'Allow', [GUID]'bf967953-0de6-11d0-a285-00aa003049e2', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'WriteProperty', 'Allow', [GUID]'bf967950-0de6-11d0-a285-00aa003049e2', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'WriteProperty', 'Allow', [GUID]'5f202010-79a5-11d0-9020-00c04fc2d4cf', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'WriteProperty', 'Allow', [GUID]'4c164200-20c0-11d0-a768-00aa006e0529', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'Self', 'Allow', [GUID]'f3a64788-5306-11d1-a9c5-0000f80367c1', 'None', [GUID]'00000000-0000-0000-0000-000000000000') $ACEs += New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList ($UserSID,'Self', 'Allow', [GUID]'72e39547-7b18-11d1-adef-00c04fd8d5cd', 'None', [GUID]'00000000-0000-0000-0000-000000000000') } Catch { Write-Error -Message ("Error while creating ACE objects:`r`n{0}`r`n{1}" -f $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { foreach ($ACE in $ACEs) { $DACL.AddAccessRule($ACE) } } Catch { Write-Error -Message ("Error while populating DACL with ACE objects:`r`n{0}`r`n{1}" -f $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Try { Set-Acl -AclObject $DACL -Path ('{0}:\{1}' -f $ComputerDomainNB, $ADObject.DistinguishedName) } Catch { Write-Error -Message ("Error while writing DACL back to {0} @ {1}:`r`n{2}`n{3}" -f $ADObject.DistinguishedName, $ComputerWDC, $Error[0].Exception.Message, $Error[0].InvocationInfo.PositionMessage) Exit } Write-Output -InputObject ('{0} is now allowed to join {1} to the domain {2}.' -f $UserName, $ComputerName, $ComputerDomain) |
Если вы используете Windows 8.1/Server 2012 R2, вам может потребоваться установить исправление из KB 3092002, иначе сценарий будет работать только при запуске от имени учётной записи, входящей в группу “Domain Admins”. Это происходит из-за ошибки в реализации командлета Set-Acl. Исправление для Windows 10 включено в последний выпуск RSAT.
Если вы испытываете какие-либо проблемы или ошибки при использовании сценария, пожалуйста, оставьте ниже комментарий или свяжитесь со мной напрямую.