This is a base runbook template developed by CT Global.
This version was first presented at Experts Live EU 2017.
<#PSScriptInfo .VERSION 1.0.0 .GUID d5033d8e-237f-42dc-84b7-6d2d20605e9f .AUTHOR Jakob Gottlieb Svendsen & Andreas Sobczyk , CTGlobal. http://www.ctglobalservices.com .COMPANYNAME CT Global .COPYRIGHT CT GLobal .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES Change Log: 1.0.0 - Initial Version #> <# .Synopsis Awesome template for Azure Automation / SMA. .DESCRIPTION Completed script and errors are logged to 1 or more eventlog events in Application Eventlog Event IDs (Application Log): 1000: Information - Successfully completed 1001: Error - General Error 1002: Error - Error in Toolkit - script continues 1003: Warning - List of machines which is active in SP but not active in SCCM 1004: Error - Server has issue, skipped to next server #> [CmdletBinding()] [OutputType([Object])] #Set to specific object type if possible (fx. if script gets a ADUser, set output type to ADUser) Param ( [Parameter (Mandatory = $true)] [String] $ResourceGroupName ) $ErrorActionPreference = "stop" $VerbosePreference = "silentlycontinue" #//---------------------------------------------------------------------------- #// #// Global constant and variable declarations #// Shared Resource retrieval (Assets) #// #//---------------------------------------------------------------------------- #Constants $Prefix = "CT-" #Assets $Credential = Get-AutomationCredential -Name "Admin" #//---------------------------------------------------------------------------- #// Procedures (Logging etc.) #//---------------------------------------------------------------------------- #region Procedures Function Add-Tracelog { <# .Synopsis Adds a tracelog message to tracelog .DESCRIPTION Uses a script scope tracelog variable to have alle scopes write to a sinlg etracelog. Outputs each message to the Verbose stream. #> param($Message, $TraceLog) $Message = "$(get-date) - $Message`n" Write-Verbose $Message if ([String]::IsNullOrEmpty($TraceLog)) { $TraceLog = $Message } else { $TraceLog += $Message } } Function ConvertTo-IndexedTable { <# .Synopsis Converts an array of objects to a array of hashtables for performance .DESCRIPTION Converts an array of objects to a hashtable of hashtables for performance The hashtable has takes one field as index, for example name and the index field can be used to filter/sort much quicker than and array of objects. (see example for details) .Example Get-CMDevice -CollectionName "All Systems" -Fast | ConvertTo-IndexedTable Name Name Value ---- ----- Object ... Name NCOP-CCMP-CCM01 the index field is available directly, while the complete object is available in the object key of the hash table. #> param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $false, Position = 0)] $IndexFieldName, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, Position = 1)] [Object]$Object ) #begin { $ReturnArray = @() } #New-Object System.Collections.ArrayList } process { @{ $IndexFieldName = $Object.$IndexFieldName Object = $Object } } #end { $ReturnArray } } #endregion #//---------------------------------------------------------------------------- #// Main routines #//---------------------------------------------------------------------------- Try { #Main Catch $script:TraceLog = $null #when testing in ISE, tracelog is not reset $StartTime = get-date Add-Tracelog -TraceLog $TraceLog -Message "Job Started at $StartTime" Add-Tracelog -TraceLog $TraceLog -Message "Running on: $env:computername" $OutputData = @{} #region Main Code #Import Modules Add-Tracelog -TraceLog $TraceLog -Message "Import SCCM Module" Import-Module AzureRM #Redirect all outputs to $null $null = . { } #endregion $EndTime = Get-date Add-Tracelog -TraceLog $TraceLog -Message "Finished at: $EndTime" Add-Tracelog -TraceLog $TraceLog -Message "Total Runtime: $($Endtime - $StartTime)" $OutputData.Add("TraceLog", $TraceLog) $OutputData.Add("Status", "Success") Write-Output $OutputData Write-Verbose $TraceLog } Catch { $ErrorMessage = $_.Exception.Message + "`nAt Line number: $($_.InvocationInfo.ScriptLineNumber)" Write-Error -Message $ErrorMessage $OutputData.Add("ErrorMessage", $ErrorMessage) $OutputData.Add("Status", "Failed") Write-Output $OutputData } #//---------------------------------------------------------------------------- #// End Script #//---------------------------------------------------------------------------- #>
Cheers great blogpost!
Hi,
Great post.
I was not able to use the function Add-Tracelog without modify it as follows:
Function Add-Tracelog {
param($Message, $TraceLog)
$Message = “$(get-date) – $Message`n”
Write-Verbose $Message
if ([String]::IsNullOrEmpty($TraceLog)) {
$script:TraceLog = $Message
}
else {
$script:TraceLog += $Message
}
}