为尚未传播的用户设置权限

时间:2021-12-06 03:01:24

I'm trying to set permissions for a folder in Powershell. My problem is that I am setting these permissions on an active directory account that is recently created on one of our head Domain Controllers. Since the account is brand new, it hasn't propagated down to any of our local DCs yet. This is causing a problem for me, since I am trying to set the folder to allow that user to have modify access and Powershell is tossing a "Some or all identity references could not be translated." error when I try to call SetAccessRule on the folder's ACL. Example code shown below.

我正在尝试在Powershell中为文件夹设置权限。我的问题是我在最近在我们的一个域控制器上创建的活动目录帐户上设置这些权限。由于该帐户是全新的,因此尚未传播到我们当地的任何DC。这对我来说是一个问题,因为我试图设置文件夹以允许该用户具有修改访问权限,而Powershell正在抛出“部分或全部身份引用无法翻译”。我尝试在文件夹的ACL上调用SetAccessRule时出错。示例代码如下所示。

#I'm actually setting more details than this for the account, but I abbreviated
#the command to make it a little more readable
New-ADUser -Name "Testy Testerson" -Server Master-DC.Domain.ca

$DirectoryLocation = '\\Fileserver\SomeDirectory'

New-Item "FileSystem::$DirectoryLocation" -ItemType directory

$ACLNeedingModification = Get-ACL "FileSystem::$DirectoryLocation"

$NewACLRule = New-Object System.Security.AccessControl.FileSystemAccessRule('Domain\Testy Testerson', 'Modify', 'Allow')

$ACLNeedingModification.SetAccessRule($NewACLRule) #Error occurs here

Set-ACL "FileSystem::$DirectoryLocation" $ACLNeedingModification

Now, my guess would be I could do a somewhat hodgepodge solution by using the SID of the user instead and just jamming that in and waiting for propagation to complete the link. That being said, I'd vastly prefer to find a way that would allow me to tell the SetAccessRule method to look at a specific DC, similar to the AD commands. The documentation for SetAccessRule was pretty sparse on how the resolution occurs, so I was wondering if anyone on here had a better way to accomplish what I'm trying to do.

现在,我的猜测是我可以通过使用用户的SID而不是干扰并等待传播来完成链接来做一些有点大杂烩的解决方案。话虽这么说,我更愿意找到一种方法,让我告诉SetAccessRule方法查看特定的DC,类似于AD命令。 SetAccessRule的文档在分辨率如何发生方面非常稀少,所以我想知道这里是否有人有更好的方法来完成我想要做的事情。

Thanks a bunch for looking!

谢谢你们一起寻找!

1 个解决方案

#1


1  

Take a look at PowerShell: Script failing because AD objects have not replicated soon enough. I'm having the same problem too and I'll try to figure it out over the next few days. If I find anything useful, I'll update this answer. This http://ss64.com/ps/set-addomainmode.html may be useful but I'm not sure yet.

看一下PowerShell:脚本失败,因为AD对象没有尽快复制。我也有同样的问题,我会在接下来的几天里试着弄明白。如果我发现任何有用的东西,我会更新这个答案。这http://ss64.com/ps/set-addomainmode.html可能有用,但我还不确定。

Edit: I wrote a cmdlet that waits for an AD object to propagate to all the domain controllers.

编辑:我写了一个cmdlet,等待AD对象传播到所有域控制器。

<#
.SYNOPSIS
    Wait for an AD object to propagate to all domain controllers.

.DESCRIPTION
    This cmdlet enumerates the domain controllers in the current domain and
    polls each one in turn until the specified object exists on each one. If
    the object doesn't propagate completely inside the timeout time span, the
    cmdlet will throw a System.TimeoutException.

.PARAMETER LDAPFilter
    The LDAP filter used to locate the object.

.PARAMETER Timeout
    The time span this command should wait before timing out.

.NOTES
    Author: Alex Barbur <alex@barbur.net>
#>
function Wait-ADObject
{
    [CmdletBinding(SupportsShouldProcess=$True)]
    param
    (
    [Parameter(Mandatory=$True)]
    [string]$LDAPFilter,
    [TimeSpan]$Timeout = '00:00:30'
    )

    # calculate when we should stop
    $stop = $(Get-Date) + $Timeout
    Write-Verbose "Will check until $stop"

    # iterate through the domain controllers
    $domain = Get-ADDomain
    foreach ($server in $domain.ReplicaDirectoryServers)
    {
        # wait for the object to replicate
        Write-Verbose "Checking $server"

        $object = $Null
        while($object -eq $Null)
        {
            # check if we've timed out
            $left = New-TimeSpan $(Get-Date) $stop
            if($left.TotalSeconds -lt 0)
            {
                # timeout
                throw [System.TimeoutException]"Object propagation has timed out."
            }

            # wait a bit and check again
            Start-Sleep -Milliseconds 250
            $object = Get-ADObject -LDAPFilter $LDAPFilter -Server $server
        }
    }
}

And you can use it like this.

你可以像这样使用它。

Import-Module ActiveDirectory
New-ADUser -SamAccountName 'doe.1'
Wait-ADObject -LDAPFilter '(sAMAccountName=doe.1)'

Hopefully it's useful to someone.

希望它对某人有用。

#1


1  

Take a look at PowerShell: Script failing because AD objects have not replicated soon enough. I'm having the same problem too and I'll try to figure it out over the next few days. If I find anything useful, I'll update this answer. This http://ss64.com/ps/set-addomainmode.html may be useful but I'm not sure yet.

看一下PowerShell:脚本失败,因为AD对象没有尽快复制。我也有同样的问题,我会在接下来的几天里试着弄明白。如果我发现任何有用的东西,我会更新这个答案。这http://ss64.com/ps/set-addomainmode.html可能有用,但我还不确定。

Edit: I wrote a cmdlet that waits for an AD object to propagate to all the domain controllers.

编辑:我写了一个cmdlet,等待AD对象传播到所有域控制器。

<#
.SYNOPSIS
    Wait for an AD object to propagate to all domain controllers.

.DESCRIPTION
    This cmdlet enumerates the domain controllers in the current domain and
    polls each one in turn until the specified object exists on each one. If
    the object doesn't propagate completely inside the timeout time span, the
    cmdlet will throw a System.TimeoutException.

.PARAMETER LDAPFilter
    The LDAP filter used to locate the object.

.PARAMETER Timeout
    The time span this command should wait before timing out.

.NOTES
    Author: Alex Barbur <alex@barbur.net>
#>
function Wait-ADObject
{
    [CmdletBinding(SupportsShouldProcess=$True)]
    param
    (
    [Parameter(Mandatory=$True)]
    [string]$LDAPFilter,
    [TimeSpan]$Timeout = '00:00:30'
    )

    # calculate when we should stop
    $stop = $(Get-Date) + $Timeout
    Write-Verbose "Will check until $stop"

    # iterate through the domain controllers
    $domain = Get-ADDomain
    foreach ($server in $domain.ReplicaDirectoryServers)
    {
        # wait for the object to replicate
        Write-Verbose "Checking $server"

        $object = $Null
        while($object -eq $Null)
        {
            # check if we've timed out
            $left = New-TimeSpan $(Get-Date) $stop
            if($left.TotalSeconds -lt 0)
            {
                # timeout
                throw [System.TimeoutException]"Object propagation has timed out."
            }

            # wait a bit and check again
            Start-Sleep -Milliseconds 250
            $object = Get-ADObject -LDAPFilter $LDAPFilter -Server $server
        }
    }
}

And you can use it like this.

你可以像这样使用它。

Import-Module ActiveDirectory
New-ADUser -SamAccountName 'doe.1'
Wait-ADObject -LDAPFilter '(sAMAccountName=doe.1)'

Hopefully it's useful to someone.

希望它对某人有用。