当我的计算机不是域成员时,非管理员如何使用 PowerShell 更改活动目录密码?
How can I, a non-administrator, change my active directory password using PowerShell, when my computer is not a member of the domain?
我以非域用户身份登录笔记本电脑。
我使用 Open VPN 连接到远程网络,并且可以通过该 VPN 访问域资源,例如 CIFS 共享,方法是在出现提示时输入我的域凭据。
我想使用 PowerShell 更改我在远程域上的密码。
我将我当前的凭据存储为 $credentials,一个 System.Management.Automation.PSCredential 对象。
我将新密码存储为 $newPassword,一个安全字符串,
当我的计算机不是域的成员时,我作为非管理员如何使用 PowerShell 更改我的 Active Directory 密码?
域的 FQDN d0-ad.domain.com 解析为域控制器 IP 地址。
我已将 netbios 名称 NP-DOMAIN 添加到主机文件,因此它也解析为域控制器。
这是我遇到问题的脚本部分:
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"
}
问题出现在
$userObject = [ADSI]$user.Path
如果我尝试访问 $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
我知道凭据是正确的并且与目录的连接有效,因为 $Searcher.FindOne() 方法正确搜索、查找并 returns 正确的用户。
那为什么我得到 "A local error has occurred."?
这个错误看起来很奇怪,但我认为这可能是因为您没有提供正确的凭据。 [ADSI]
类型加速器只是一个 shorthand 用于创建 DirectoryEntry
对象。所以 [ADSI]$user.Path
相当于创建一个 DirectoryEntry
就像你在代码顶部所做的那样,只是没有用户名和密码。
所以你可以:
- 像在文件顶部那样创建它:
$userObject = New-Object -TypeName System.DirectoryServices.DirectoryEntry $user.Path, $credentials.UserName, $($credentials.GetNetworkCredential().password)
或者,
- 在
SearchResult
上致电 GetDirectoryEntry()
。 DirectoryEntry
对象 returns 将设置与 SearchRoot
上相同的凭据:
$userObject = $user.GetDirectoryEntry()
我以非域用户身份登录笔记本电脑。
我使用 Open VPN 连接到远程网络,并且可以通过该 VPN 访问域资源,例如 CIFS 共享,方法是在出现提示时输入我的域凭据。
我想使用 PowerShell 更改我在远程域上的密码。
我将我当前的凭据存储为 $credentials,一个 System.Management.Automation.PSCredential 对象。
我将新密码存储为 $newPassword,一个安全字符串,
当我的计算机不是域的成员时,我作为非管理员如何使用 PowerShell 更改我的 Active Directory 密码?
域的 FQDN d0-ad.domain.com 解析为域控制器 IP 地址。 我已将 netbios 名称 NP-DOMAIN 添加到主机文件,因此它也解析为域控制器。
这是我遇到问题的脚本部分:
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"
}
问题出现在
$userObject = [ADSI]$user.Path
如果我尝试访问 $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
我知道凭据是正确的并且与目录的连接有效,因为 $Searcher.FindOne() 方法正确搜索、查找并 returns 正确的用户。
那为什么我得到 "A local error has occurred."?
这个错误看起来很奇怪,但我认为这可能是因为您没有提供正确的凭据。 [ADSI]
类型加速器只是一个 shorthand 用于创建 DirectoryEntry
对象。所以 [ADSI]$user.Path
相当于创建一个 DirectoryEntry
就像你在代码顶部所做的那样,只是没有用户名和密码。
所以你可以:
- 像在文件顶部那样创建它:
$userObject = New-Object -TypeName System.DirectoryServices.DirectoryEntry $user.Path, $credentials.UserName, $($credentials.GetNetworkCredential().password)
或者,
- 在
SearchResult
上致电GetDirectoryEntry()
。DirectoryEntry
对象 returns 将设置与SearchRoot
上相同的凭据:
$userObject = $user.GetDirectoryEntry()