验证远程域的凭据

Validate credentials for remote domain

任何人都可以建议如何在远程域上验证凭据吗?

我的环境有多个域,它们之间没有定义信任关系。 我有一个 Powershell 脚本,需要访问驻留在另一个域中的服务器上的共享文件夹,这显然需要身份验证。在访问它之前,我需要验证凭据以避免锁定(脚本可以针对多个服务器 运行)。

过去我用过这个wonderful script,它使用当前域进行验证,但我无法让它在远程域上工作。 我试过这是(略微修改了上面 link 的脚本):

function Test-Cred {
           
    [CmdletBinding()]
    [OutputType([String])] 
       
    Param ( 
        [Parameter( 
            Mandatory = $false, 
            ValueFromPipeLine = $true, 
            ValueFromPipelineByPropertyName = $true
        )] 
        [Alias( 
            'PSCredential'
        )] 
        [ValidateNotNull()] 
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()] 
        $Credentials
    )
    $Domain = $null
    $Root = $null
    $Username = $null
    $Password = $null
      
    If($Credentials -eq $null)
    {
        Try
        {
            $Credentials = Get-Credential "domain$env:username" -ErrorAction Stop
        }
        Catch
        {
            $ErrorMsg = $_.Exception.Message
            Write-Warning "Failed to validate credentials: $ErrorMsg "
            Pause
            Break
        }
    }
      
    # Checking module
    Try
    {
        # Split username and password
        $Username = $credentials.username
        $Password = $credentials.GetNetworkCredential().password
  
        # Get Domain
        ###$Root = "LDAP://" + ([ADSI]'').distinguishedName
        $Root = "LDAP://DC=remote_domain,DC=com"      ### statically define the remote domain
        $Domain = New-Object System.DirectoryServices.DirectoryEntry($Root,$UserName,$Password)
    }
    Catch
    {
        $_.Exception.Message
        Continue
    }
  
    If(!$domain)
    {
        Write-Warning "Something went wrong"
    }
    Else
    {
        If ($domain.name -ne $null)
        {
            return "Authenticated"
        }
        Else
        {
            $Domain    ### diagnosing the error
            return "Not authenticated"
        }
    }
}

我收到以下错误:

format-default : The following exception occurred while retrieving member "distinguishedName": "The user name or
password is incorrect.
"
    + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
    + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand

username/password 100% 正确。 谢谢

编辑 1

我发现以下 blog post 介绍了如何使用 .Net 程序集处理 Active Directory。以下效果很好

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
#store credentials (of account with appropriate permissions)
$creds = Get-Credential 
#set the domain name
$dn = 'contoso.com' 

#Create the principal context object (so to say connect to a domain with the credentials provided)
$pc = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::`
Domain,$dn,$($creds.UserName),$($creds.GetNetworkCredential().Password))

我假设我可以在 If 语句中使用它来实现我需要的。诚然,我不了解.Net的方式,有点可怕,但我必须学习它。

编辑 2

这是我拼凑的:

Function Test-Cred
{
    [CmdletBinding()]
    [OutputType([String])] 
       
    Param ( 
        [Parameter( 
            Mandatory = $false, 
            ValueFromPipeLine = $true, 
            ValueFromPipelineByPropertyName = $true
        )] 
        [Alias( 
            'PSCredential'
        )] 
        [ValidateNotNull()] 
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()] 
        $Credentials
    )
    
    Add-Type -AssemblyName System.DirectoryServices.AccountManagement      

    # Checking module

    $Validated = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::Domain,'remote_domain',$($Credentials.UserName),$($Credentials.GetNetworkCredential().Password))
 
    If ($Validated.ConnectedServer)
    {
        Return "Authenticated"
    }
    Else
    {
        Return "Not authenticated"
    }
}

有任何反馈吗?

编辑 3

嗯,EDIT 2 不适用于 Powershell 4,grrr

Method invocation failed because [System.DirectoryServices.AccountManagement.PrincipalContext] dies not contain method named 'new'

我不得不让它像这样工作:

$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$ContextName = 'target_domain.com'
$Validated = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ContextType, $ContextName, $($Credentials.UserName),$($Credentials.GetNetworkCredential().Password)

这是我的此测试函数的最终版本,适用于 5.1 之前的 Powershell 版本。

Function Test-Cred
    {
        [CmdletBinding()]
        [OutputType([String])] 
           
        Param ( 
            [Parameter( 
                Mandatory = $false, 
                ValueFromPipeLine = $true, 
                ValueFromPipelineByPropertyName = $true
            )] 
            [Alias( 
                'PSCredential'
            )] 
            [ValidateNotNull()] 
            [System.Management.Automation.PSCredential]
            [System.Management.Automation.Credential()] 
            $Credentials
        )
        
        # Checking module
        
        Add-Type -AssemblyName System.DirectoryServices.AccountManagement      

        $ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
        $ContextName = 'remote_domain.com'
        $Validated = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ContextType, $ContextName, $($Credentials.UserName),$($Credentials.GetNetworkCredential().Password)       
        If ($Validated.ConnectedServer)
        {
            Return "Authenticated"
        }
        Else
        {
            Return "Not authenticated"
        }
    }