Lightweight PowerShell framework providing logging and configuration for automated tasks.
- Clone or copy this folder anywhere on your server or network share (e.g., C:\PSsvctask, D:\Scripts\PSsvctask, \server\share\PSsvctask)
- Edit
ServiceSettings.psd1(must be in same folder as PSsvctask.ps1) and set your paths, hostname, and service account - Edit
ServiceLog.psd1(see Basic Configuration) and set your paths for logging - Run a task:
.\PSsvctask.ps1 ExampleTask - Check logs in the
Logs\folder
Edit ServiceSettings.psd1:
ServiceAccount = "YourServiceAccount" # Tasks run in test mode if not this user
ServiceHost = "SERVERNAME" # Tasks run in test mode if not this hostname
ModulesPath = "C:\PSsvctask\Modules" # Where shared code lives
TasksPath = "C:\PSsvctask\Tasks" # Where task scripts liveEdit Modules\ServiceLog\ServiceLog.psd1 for log configuration:
LocalLogPath = "C:\PSsvctask\Logs" # Log path when running on ServiceHost
RemoteLogPath = "C:\PSsvctask\Logs" # Log path when running elsewhere
LogRetentionDays = 10 # Auto-delete log folders older than thisNote: ModulesPath and TasksPath can be anywhere on the system or UNC paths (e.g., \\server\share\Tasks) - they don't have to be in the same folder as PSsvctask.ps1. You can also rename PSsvctask.ps1 to fit your naming conventions.
Test mode automatically activates when running under a different account or hostname. Use this to safely test and debug tasks without making actual changes. Test mode pauses at the end for review. Production mode (correct account + hostname) runs unattended.
From PowerShell:
.\PSsvctask.ps1 ExampleTaskFrom Task Scheduler, set:
- Program:
powershell.exe - Arguments:
-ExecutionPolicy Bypass -File "<path>\PSsvctask.ps1" ExampleTask - Start in:
<path>(folder containing PSsvctask.ps1)
Logs are created in Logs\YYYY-MM-DD\TaskName.log automatically.
Example: Create a task that cleans old temporary files
- Create
Tasks\CleanTempFiles.ps1:
$OldFiles = Get-ChildItem -Path $TaskSettings.CleanupPath -Recurse -File |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$TaskSettings.RetentionDays) }
Write-ServiceLog "Found $($OldFiles.Count) files older than $($TaskSettings.RetentionDays) days"
foreach ($File in $OldFiles) {
if (-not $global:ServiceTestMode) {
Remove-Item $File.FullName -Force
Write-ServiceLog "Deleted: $($File.FullName)" -Status $true
} else {
Write-ServiceLog "Would delete: $($File.FullName)" -Status $true
}
}- Create
Tasks\CleanTempFiles.psd1:
@{
ServiceModules = @()
PowerShellModules = @()
LogFileNameTime = $false
# Task-specific settings
CleanupPath = "C:\Temp"
RetentionDays = 30
}Required Task settings:
ServiceModules- Array of custom modules from your Modules folder to loadPowerShellModules- Array of standard PowerShell modules to importLogFileNameTime- When$true, creates a task-specific subfolder and includes time in the log filename (e.g.,Logs\YYYY-MM-DD\TaskName\TaskName - HH MM TT.log). When$false(default), logs go directly in the date folder (e.g.,Logs\YYYY-MM-DD\TaskName.log). Use$truefor tasks that run multiple times per day
- Run it:
.\PSsvctask.ps1 CleanTempFiles
Note: Any key you add to the task's .psd1 file is accessible via $TaskSettings.YourKey in your script.
Write-ServiceLog "message" # [INFO] with timestamp
Write-ServiceLog "message" -Status $true # [PASS] with timestamp
Write-ServiceLog "message" -Status $false # [FAIL] with timestamp
Write-ServiceLog -Line # Adds separator lineCheck $global:ServiceTestMode in your scripts to prevent changes during testing.
Create modules when you have code used by multiple tasks. Example: An email notification module.
-
Create folder:
Modules\EmailNotify\ -
Create
EmailNotify.psm1:
## EXAMPLE MODULE
# Initialize module settings
if (-not $script:Settings) { $script:Settings = (Import-PowerShellDataFile -Path (Join-Path $PSScriptRoot ((Split-Path $PSScriptRoot -Leaf) + '.psd1'))).PrivateData }
# Import modules
Get-ChildItem -Path $PSScriptRoot -Filter '*.ps1' -File | ForEach-Object { . $_.FullName }- Create
EmailNotify.psd1:
@{
RootModule = "EmailNotify.psm1"
ModuleVersion = "1.0.0"
PrivateData = @{
SmtpServer = "smtp.company.com"
FromAddress = "tasks@company.com"
ToAddress = "admin@company.com"
}
}- Create
Send-TaskAlert.ps1in the same folder:
function Send-TaskAlert {
param([string]$Subject, [string]$Body)
Send-MailMessage -SmtpServer $script:Settings.SmtpServer `
-From $script:Settings.FromAddress `
-To $script:Settings.ToAddress `
-Subject $Subject -Body $Body
}-
Reference in task .psd1 files:
ServiceModules = @("EmailNotify") -
Use in tasks:
Send-TaskAlert "Cleanup Complete" "Deleted 50 files"
Note: ServiceLog module is required and automatically loaded for all tasks.