[英]How can I, a non-administrator, change my active directory password using PowerShell, when my computer is not a member of the domain?
I'm logged on to a laptop as a non-domain user.我以非域用户身份登录到笔记本电脑。
I'm connected to a remote network using Open VPN, and can access domain resources through that VPN, such as an CIFS share, by entering my domain credentials when prompted.我使用 Open VPN 连接到远程网络,并且可以通过该 VPN 访问域资源,例如 CIFS 共享,在出现提示时输入我的域凭据。
I want to use PowerShell to change my password on the remote domain.我想使用 PowerShell 更改远程域上的密码。
I have my current credentials stored as $credentials, a System.Management.Automation.PSCredential object.我将当前凭据存储为 $credentials,一个 System.Management.Automation.PSCredential 对象。
I have my new password stored as $newPassword, a secure string,我将我的新密码存储为 $newPassword,一个安全字符串,
How can I, a non-administrator, change my active directory password using PowerShell, when my computer is not a member of the domain?当我的计算机不是域成员时,非管理员如何使用 PowerShell 更改我的活动目录密码?
The FQDN of the domain, d0-ad.domain.com, resolves to a domain controller IP address.域的 FQDN d0-ad.domain.com 解析为域控制器 IP 地址。 I have added the netbios name, NP-DOMAIN, to the hosts file, so it also resolves to a domain controller.我已将 netbios 名称 NP-DOMAIN 添加到主机文件,因此它也解析为域控制器。
This is the section of the script I'm having trouble with:这是我遇到问题的脚本部分:
Write-Verbose "Setting up DirectoryEntry object"
$DomainEntry = New-Object -TypeName System.DirectoryServices.DirectoryEntry "LDAP://$($netBiosName)" ,$credentials.UserName,$($credentials.GetNetworkCredential().password)
Write-Verbose "Setting up DirectorySearcher object"
$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $DomainEntry
$userName = $($credentials.UserName).Replace("$($netBiosName)\","")
Write-Verbose "Username set as $($userName)"
$Searcher.Filter = "(samaccountname=$($userName))"
$user = $Searcher.FindOne()
$userObject = [ADSI]$user.Path
if ($userObject) {
Write-Verbose "Changing password for user: $($user.Path)"
$userObject.ChangePassword($credentials.GetNetworkCredential().password, [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($NewPassword)))
} else {
Write-Verbose "User $($username) not found"
throw "User $($username) not found"
}
The problem occurs at问题发生在
$userObject = [ADSI]$user.Path
If I try to access $userObject I receive the error:如果我尝试访问 $userObject 我收到错误:
format-default : The following exception occurred while retrieving member "distinguishedName": "A local error has occurred. " + CategoryInfo : NotSpecified: (:) [format-default], ExtendedTypeSystemException + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand format-default :检索成员“distinguishedName”时发生以下异常:“发生本地错误。” + CategoryInfo : NotSpecified: (:) [format-default], ExtendedTypeSystemException +fullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand
I know the credentials are correct and the connection to the directory works because the $Searcher.FindOne() method correctly searches for, finds, and returns the correct user.我知道凭据正确并且与目录的连接有效,因为 $Searcher.FindOne() 方法正确搜索、查找并返回正确的用户。
So why am I getting "A local error has occurred."?那么为什么我会收到“发生本地错误。”?
The error does seem odd, but I think it's probably because you're not giving it proper credentials.这个错误看起来很奇怪,但我认为这可能是因为你没有给它适当的凭据。 The [ADSI]
type accelerator is just a shorthand for creating a DirectoryEntry
object. [ADSI]
类型加速器只是创建DirectoryEntry
对象的简写。 So [ADSI]$user.Path
is the equivalent of creating a DirectoryEntry
like you did at the top of your code, except with no username and password.所以[ADSI]$user.Path
相当于创建一个DirectoryEntry
就像您在代码顶部所做的那样,除了没有用户名和密码。
So you can:这样你就可以:
$userObject = New-Object -TypeName System.DirectoryServices.DirectoryEntry $user.Path, $credentials.UserName, $($credentials.GetNetworkCredential().password)
or,或者,
GetDirectoryEntry()
on the SearchResult
.在SearchResult
上调用GetDirectoryEntry()
。 The DirectoryEntry
object it returns will have the same credentials set on it as what was set on the SearchRoot
:它返回的DirectoryEntry
对象将具有与SearchRoot
上设置的相同的凭据设置:$userObject = $user.GetDirectoryEntry()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.