SharePoint.Password.Manager.psm1


function Change-SPServicePassword {
<#
   .SYNOPSIS
      Change SharePoint Services account password.
       
   .DESCRIPTION
      This module allows administrator to change SharePoint Services account password easily throughout all the servers.
      Before executing this module, the all service account password must be already updated in Active Directory.
      The Administrator then create CSV files (UserName,NewPassword) - where the Change-SPServicePassword will iterate and find all relevant Managed Account, Windows Services.
       
       
   .PARAMETER passwordCsv
      Mandatory. CSV contains servicesaccount and theirs new password. The script will search all services that uses the ServiceAccounts in the list
      and perform password update.
       
   .PARAMETER farmAction
      Optional. True/False, to indicate that the function will be executed on Farm's managed account or non Farm's managed account. Default: false.
         
   .INPUTS
      Parameters above
    
   .OUTPUTS
      None
    
   .NOTES
      Version: 1.0
      Author: Riwut Libinuko
      Creation Date: 11/01/2018
      Last Update: 11/03/2018
       
   .EXAMPLE
      Change-SPServicePassword -passwordCsv 'D:\code\ChangePassword.csv' -farmAction $true
      Change-SPServicePassword -passwordCsv 'D:\code\ChangePassword.csv'
 
    Change-SPServicePassword -farmAction $rue, must be executed at least once in any of the server member.
 
    .EXAMPLE
      Change-SPServicePassword -passwordCsv 'D:\code\ChangePassword.csv'
 
    This command must be executed in all server members.
    
#>


    Param( 
        [string] $passwordCsv = 'D:\code\ChangePassword\ChangePassword_sample.csv',
        [switch] $farmAction = $false
    )

    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
    Import-Module WebAdministration

    $passwords = Import-Csv $passwordCsv
    #Excluded - will be handled by other script
    $excludeService = @('AppFabricCachingService', 'FabricHostSvc','Service Bus Gateway','Service Bus Message Broker','Service Bus Resource Provider','WorkflowServiceBackend')

    Update-ServicePassword -passwords $passwords -farmAction $farmAction
    Update-AppPool -passwords $passwords -farmAction $farmAction
    Update-ManagedAccount -passwords $passwords -farmAction $farmAction
    Update-ContentAccount -passwords $passwords -farmAction $farmAction
}


function Change-SPWorkflowPassword {
<#
   .SYNOPSIS
      Change WorkflowHost and ServiceBus account password.
       
   .DESCRIPTION
      This module allows administrator to change WorkflowHost and ServiceBus account password.
      Before executing this module, the all service account password must be already updated in Active Directory.
      The Administrator then create CSV files (UserName,NewPassword) - where the Change-SPWorkflowPassword will find password for the RunAsService.
       
       
   .PARAMETER passwordCsv
      Mandatory. CSV contains servicesaccount and theirs new password. The script will search all services that uses the ServiceAccounts in the list
      and perform password update.
       
   .PARAMETER service
      Mandatory. Workflow/ServiceBus, Select between Workflow or ServiceBus - runAsService password modification.
         
   .INPUTS
      Parameters above
    
   .OUTPUTS
      None
    
   .NOTES
      Version: 1.0
      Author: Riwut Libinuko
      Creation Date: 11/01/2018
      Last Update: 11/03/2018
       
   .EXAMPLE
      Change-SPWorkflowPassword -passwordCsv 'D:\code\ChangePassword.csv' -service Workflow
 
    Change WorkflowHost RunAsService account password.
 
    .EXAMPLE
      Change-SPWorkflowPassword -passwordCsv 'D:\code\ChangePassword.csv' -service ServiceBus
 
    Change ServiceBusHost RunAsService account password.
    
#>

    Param(
        [ValidateSet('Workflow','ServiceBus')]
        [String]$service,
        [string] $passwordCsv = 'D:\code\ChangePassword\ChangePassword_sample.csv'
    )

    $passwords = Import-Csv $passwordCsv

    if($service -eq "Workflow") {    
        $account = (Get-WFFarm).RunAsAccount
        $userPassword = Find-Password -username $account -passwords $passwords

        if($userPassword -ne $null) {                
            Write-Host "Updating WorkflowHost password.." -NoNewline
            Stop-WFHost -Verbose
            Update-WFHost -RunAsPassword $userPassword â€“Verbose
            Start-WFHost -Verbose
            Write-Host "Done!" -ForegroundColor Green
        } else {
           Write-Host "Can not find WorkflowHost password!" -ForegroundColor Red
        }
    } 

    if($service -eq "ServiceBus") {
        $account = (Get-SBFarm).RunAsAccount
        $userPassword = Find-Password -username $account -passwords $passwords

        if($userPassword -ne $null) {
            Write-Host "Updating ServiceBus password.." -NoNewline
            Stop-SBHost -Verbose
            Update-SBHost -RunAsPassword $userPassword â€“Verbose
            Start-SBHost -Verbose
            Write-Host "Done!" -ForegroundColor Green
        } else {
           Write-Host "Can not find ServiceBus password!" -ForegroundColor Red
        }
    }
}

function Find-User{
    Param(
        [string] $username,
        $passwords
    )

    $user = $passwords |? { $_.Username -eq $username }
    if($user -eq $null)
    {
       Write-Host "Can not find $($user.Username)" -ForegroundColor Red
       return $null
    }
    return $user
}

function Find-Password {
    Param(
        [string] $username,
        $passwords
    )

    $userPassword = Find-User -username $account -passwords $passwords

    if($userPassword -eq $null)
    {
        return $null
    } else {
        $newpwd1 = $userPassword.NewPassword
        $newpassword =  ConvertTo-SecureString -String $newpwd1 -AsPlainText -Force
        return $newpassword
    }
}

#1 One time - Managed account
function Update-ManagedAccount
{
    Param( 
        $passwords,
        [switch] $farmAction = $false
    )

   if($farmAction -eq $false) {
       return
   }

    write-host "Update SPManaged account password..."
    $passwords | foreach {      
    $username = $_.Username
    $newpwd1 = $_.NewPassword
    $newpassword =  ConvertTo-SecureString -String $newpwd1 -AsPlainText -Force
        
        <#if ($newpasswords)
        {
            Write-Host "Updating SPManagedAccount {$username} password, to new"
            #Set-SPManagedAccount -Identity $username -NewPassword $newpassword -ConfirmPassword $newpassword -Confirm:$false
        }
        else
        {#>

    Write-Host "Updating SPManagedAccount $($username) password, matching AD..." -NoNewline
    Set-SPManagedAccount -Identity $username -ExistingPassword $newpassword -Confirm:$false -UseExistingPassword:$true
    Write-Host "Done!" -ForegroundColor Green
       # }
   }
}

#2 One time - Default Content Account

function Update-ContentAccount
{
    Param( 
        $passwords,
        [switch] $farmAction = $false
    )

    if($farmAction -eq $false) {
       return
    }
    write-host "Update Default content search account password..."
    Get-SPEnterpriseSearchServiceApplication |% {
        $spService = $_
        $content = New-Object -TypeName Microsoft.Office.Server.Search.Administration.Content -ArgumentList $spService

        Write-host "Updating ContentSearch $($spService.Name) $($content.DefaultGatheringAccount) password, matching AD.." -NoNewline
        $userExist = Find-User -username $content.DefaultGatheringAccount -passwords $passwords
        if($userExist -ne $null)
        {
            $username = $userExist.Username
            $newpwd1 = $userExist.NewPassword
            $newpassword =  ConvertTo-SecureString -String $newpwd1 -AsPlainText -Force

            Set-SPEnterpriseSearchServiceApplication -Identity $spService -DefaultContentAccessAccountName $username -DefaultContentAccessAccountPassword $newpassword
            Write-Host "Done!" -ForegroundColor Green
        }
    }
}


#3 All Servers - Update AppPool password
function Update-AppPool {

    Param( 
        $passwords,
        [switch] $farmAction = $false
    )

    if($farmAction -eq $true) {
       return
    }
   Write-Host "Stoping IIS. "
   iisreset /stop /noforce
   $passwords |% {
        $username = $_.Username
        $newpwd1 = $_.NewPassword
        $newpassword =  ConvertTo-SecureString -String $newpwd1 -AsPlainText -Force

        $appPools = gci IIS:\AppPools |? { $_.processModel.userName -eq $username }
        $appPools |% {
           $pool = $_
           Write-Host "Updating AppPool: $($pool.Name) $($username) password, matching AD..." -NoNewline
           $pool.processModel.userName = $username
           $pool.processModel.password = $newpwd1
           $pool.processmodel.identityType = 3
           $pool | Set-Item
           Write-Host "Done!" -ForegroundColor Green           
        }
   }

   Write-Host "Starting IIS..."
   iisreset /start /noforce
}

#4 All Servers - Update Service password
function Update-ServicePassword {
    Param( 
        $passwords,
        [switch] $farmAction = $false
    )

    if($farmAction -eq $true) {
       return
    }

    Write-Host "Updating Password for Services"
   $passwords |% {
       $username = $_.Username
       $newpassword = $_.NewPassword

       Get-WmiObject win32_Service |? { $_.startname -eq $username -and $_.Name -notin $excludeService} |% {
           $service = $_
           write-host "Updating Service: $($service.Name) $($username) password, matching AD.." -NoNewline
           $status = $service.Change($null,$null,$null,$null,$null,$null, $username, $newpassword)
           Write-Host "Status: $($status.ReturnValue)" -NoNewline
           Write-Host "Done!" -ForegroundColor Green
       }

       Write-Host "Stopping services"
       Get-WmiObject win32_Service |? {
         $_.startname -eq $username -And $_.state -ne "Stopped" -and $_.startmode -ne "Disabled" } | Stop-Service -Force

        Write-Host "Starting services"
       Get-WmiObject win32_Service |? { 
        $_.startname -eq $username -And $_.state -ne "Running" -and $_.startmode -ne "Disabled" } | Start-Service
   }
}

Export-ModuleMember -Function Change-SPServicePassword, Change-SPWorkflowPassword