PS: Forcing Preferences

3 minute read

Description:

So I’ve been watching the 90 part Don Jones series on CBT Nuggets on Powershell and one thing he is always saying is “Don’t assume what the user will use your script for… don’t force your preferences on other people” like comments. Well if you ever stumble upon my script and have issues with my setup, here are somethings you can do to fix.

To Resolve:

  1. UPDATE 2018-05-05: I have refactored my scripts to not force logging by doing the following:

    Begin
       {       
          If ($($Logfile.Length) -gt 1)
          {
                $EnabledLogging = $True
          }
          Else
          {
                $EnabledLogging = $False
          }
             
             
          Filter Timestamp
          {
                "$(Get-Date -Format "yyyy-MM-dd hh:mm:ss tt"): $_"
          }
    
          If ($EnabledLogging)
          {
                # Create parent path and logfile if it doesn't exist
                $Regex = '([^\\]*)$'
                $Logparent = $Logfile -Replace $Regex
                If (!(Test-Path $Logparent))
                {
                   New-Item -Itemtype Directory -Path $Logparent -Force | Out-Null
                }
                If (!(Test-Path $Logfile))
                {
                   New-Item -Itemtype File -Path $Logfile -Force | Out-Null
                }
          
                # Clear it if it is over 10 MB
                $Sizemax = 10
                $Size = (Get-Childitem $Logfile | Measure-Object -Property Length -Sum) 
                $Sizemb = "{0:N2}" -F ($Size.Sum / 1mb) + "Mb"
                If ($Sizemb -Ge $Sizemax)
                {
                   Get-Childitem $Logfile | Clear-Content
                   Write-Verbose "Logfile has been cleared due to size"
                }
                # Start writing to logfile
                Start-Transcript -Path $Logfile -Append 
                Write-Output "####################<Script>####################"
                Write-Output "Script Started on $env:COMPUTERNAME" | TimeStamp
          }
       }
          
       Process
       {   
          Try
          {
                   
                   
                # Script      
                # Here
          
    
          }
          Catch
          {
                Write-Error $($_.Exception.Message)
          }
       }
    
       End
       {
          If ($EnableLogging)
          {
                Write-Output "Script Completed on $env:COMPUTERNAME" | TimeStamp
                Write-Output "####################</Script>####################"
                Stop-Transcript
          }
    
    • This removed Event logging from my scripts and uses the native Start-Transcript instead. Now if you don’t want logging, simply remove the prefilled file at:
    Param
       (
          [String]$Logfile = "$PSScriptRoot\..\Logs\Set-Template.log"
       )
    

  1. The first, is pretty easy “Set-Console”. This is a function that lives in my helpers.psm1 file that simply sets the console to have green text on a black background. The fix for this one is simple, just delete the “set-console” line in the begin blocks of my scripts.

  2. Logging. This is the one that will require multiple rewrites of my code, and quite frankly, I’m not going to do it. But I will acknowledge it and even tell you how to rewrite my code if you “borrow” it.

    • The begin and end blocks will be the easiest. What we are doing here is wrapping everything in an if statement.
    Pseudo code:
    
    If ($logfile.lenght -ge 1)  
    {  
    Use my logging function  
    }  
    Else  
    {  
    Use what you prefer (?Write-Verbose/Output)  
    }
    
    • For example:
    # Begin:
    If ($Logfile.Length -ge 1)
    {
    $PSDefaultParameterValues = @{ "*-Log:Logfile" = $Logfile }
    Set-Variable -Name "Logfile" -Value $Logfile -Scope "Global"
    Start-Log
    Set-Console
    }
    Else
    {
    Set-Console
    }
    
    # End:
    If ($Logfile.Length -ge 1)
    {
    Stop-Log
    }
    
    • The hard part. For every “Log $whatever” you find in my scripts (lots of them!), you will have to do:
    If ($Logfile.Length -ge 1)
    {
    Log "my text here"
    }
    Else
    {
    Write-Verbose "my text here"
    Write-Output "my text here"
    }
    
    • In addition,one of my internal functions “Set-Regentry” uses the logging (line 10):
    Else
    {
    If (!($($Bin.length -gt 0)))
    {
    $Bin = Read-Host "Paste the =hex: here"
    }
    # Example: $Bin = "03,00,00,00,cd,9a,36,38,64,0b,d2,01"
    $Hex = $Bin.Split(',') | ForEach-Object -Process { "0x$_" }
    New-ItemProperty -Path $Path -Name $Name -PropertyType Binary -Value ([byte[]]$Hex) -Force | Out-Null
    Write-Log "Added Key: $Name at $Path" -Color Gray
    }
    # You will need to edit line 10 to be "Write-Verbose" or "Write-Output" depending on what you are wanting to achieve.
    
  3. Same for my try/catch blocks:

    Catch
    {
    If ($Logfile.Length -ge 1)
    {
    Write-ErrorLog -Message $($_.Exception.Message) -ExitGracefully
    }
    Else
    {
    Write-Error -Message $($_.Exception.Message)
    }
    }