Setting Cross-Forest Passwords

In my test labs, some of the more specialized testing labs (perf, specifically) have one-way trust with the larger test domain.  This means I can set (or, in the case of some coworkers) reset credentials when they don’t log into the smaller domain frequently enough.  You can do it via dsa.msc and connecting it to the domain that trusts the current domain, but it’s also something that happens enough that I may as well script it.

 function Set-AdForestPassword
{
    param (
        [string[]]$Domain = @( $env:UserDnsDomain.ToLower()),
        [string[]]$Username = @($env:UserName)        
    );

    begin
    {
        if (!(Get-Command Get-AdUser)) { Import-Module Active-Directory; }
    
    } # begin

    process
    {
        foreach ($myDomain in $Domain)
        {
            foreach ($myUser in $Username)
            {
                Write-Progress "Getting DN" "$myDomain\$myUser";

                if ($dn = (Get-AdUser -Identity $myuser -Server $myDomain -ErrorAction SilentlyContinue).DistinguishedName)
                {
                    $secureString = Read-Host -AsSecureString -Prompt "Enter password for $myDomain\$myUser";
                    if ($secureString -and
                        ($password = [System.Runtime.InteropServices.marshal]::PtrToStringAuto(
                            [System.Runtime.InteropServices.marshal]::SecureStringToBSTR($secureString)
                        ))
                    ) {

                        Write-Progress "Updating password" "$myDomain\$myUser";
                        $myDn = "LDAP://$dn";
                        $user = [ADSI]$myDn;
                        $user.PsBase.Invoke("SetPassword", $password);
                        $user.PsBase.CommitChanges();

                    } # if ($secureString = Read-Host...)
                    else
                    {
                        Write-Warning "No password entered for $myDomain\$myUser. Skipping.";
                    
                    } # if ($secureString = Read-Host...) ... else
                
                } # if ($dn = (Get-AdUser...
                else
                {
                    Write-Warning "Cannot get DN for $myDomain\$myUser.  Skipping.";

                } # if ($dn = (Get-AdUser... else

            } # foreach ($myUser in $Username)
        
        } # foreach ($myDomain in $Domain)

    } # process

} # function Set-AdForestPassword

By default, it will reset the account in the current domain, but the -Domain parameter allows me to set the credentials for someone in our perf lab.