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
}
}