Overview

This is Part 5 of a multi-part series on managing local admin passwords. In this part I will discuss how to log the results of each function within the solution to a log file for troubleshooting purposes.  In case you missed it:

Here is Part 1 - Overview

Here is Part 2 - Random Password Generation

Here is Part 3 - Secure Active Directory Attribute Update

Here is Part 4 - Update Local Account's Password

If you want to skip straight to the script you can copy it from this post directly, or you can download the script which is attached to this post as a text file. The attached script should be opened in PowerShell ISE to display properly.

The Problem


Keeping the local password of a workstation synchronized with the password that is viewable by authorized administrators can be a tricky task. If one of the steps in the password management solution were to fail, without some sort of log it would be next to impossible to figure out what is not working properly. To assist in the troubleshooting process, I wrote extensive logging throughout each function. In the final post, the entire solution will be available and it will include all of the functions with the logging capability enabled. Lets examine that logging function in depth below.

The Solution


The following function takes input from all of the other functions and generates a log file in the configured location when it is called. I have also seen many script and programs that generate a log file which grows endlessly, and needlessly takes up hard drive space; the following function deletes the log file and starts over once the file reaches 500K. Many things can go wrong during the password management process including; failure to connect to Active Directory, failure to update the AD attribute, and failure to update the local account's password. Each function calls the following log function as they perform their operations to ensure the outcome of each task is properly documented.

If no logging is desired, that is also an option.

#==================================================================================
# Global Variables
#==================================================================================
$Logging            =$true                      #[$true|$false] writes log file to $LogDir if $true
$LogDir              ='C:\ProgramData'   #Location of Log file
$LogFileName   ='PwdLog.log'           #Name of log file

#==================================================================================
# Output to Log file (Delete Log File If Size Is Over 500KB)
#==================================================================================
function fnLog
{param([Parameter(Mandatory=$true)][string]$Data,[Parameter(Mandatory=$true)][string]$LogPath,[Parameter(Mandatory=$true)][string]$LogFileName)

    #Checks to see if Logging is enabled
    if($Logging -ne $true){Return}

    #Builds Log Path
    $LogFile = "$LogPath\$LogFileName"

    #Checks for current log file
    if(Test-Path $LogFile){
      $File = Get-Item $LogFile
      #Deletes current log file if over 500KB
      if($File.Length -ge 500000){Remove-Item $File}
    }
    try{
        #Outputs to log file
        $TimeStamp = (get-date).toshortdatestring() + " " + (get-date).tolongtimestring()

        #Outputs to log file
        "`n- $TimeStamp " + $env:COMPUTERNAME + " $Data" | Add-Content $LogFile -Encoding Unicode
    }
    catch{Return "Unable to write to log file"}
}

Below is a screen shot of some sample entries generated by fnLog when called from various functions within the password management solution.

Still to Come

The upcoming parts in this series will explain how to do the following:

  • Create a confidential attribute to store the local admin password
  • Create fnMain to control the order in which all of the functions are called
  • Create a XAML based secure password viewer to retrieve the local admin password

Each portion of the solution is modularized using functions which allows the IT administrator to make use of all or just parts of the solution and allows the IT administrator to easily integrate any portion they wish into a larger script or even a different solution entirely. So stay tuned as Part 6 discusses how to create a confidential Active Directory Attribute to store the password in Active Directory.