ScriptsToProcess Scheduled Task

Before we really get started, I think it’s helpful to first mention that I was recently deep in a project at work that doesn’t include Active Directory, but does include Windows clients. Therefore, I had do things in ways that could have been made easier had I had Active Directory to leverage.

I’ve long known that there’s a ScriptsToProcess option for PowerShell script modules that use a module manifest file. First, a script module is most often a collection of functions inside a script written, PowerShell module — a .psm1 file. Second, a .psd1 file is the module manifest file, and it contains information, among other things, about the module itself. One of the things that can be used in this file, is ScriptsToProcess, where a path, or paths, to a .ps1 file(s) can be included. This ultimately means a script can be run the moment your module is imported. ScriptsToProcess allows for an environment to be set up the way you want, prior to anyone actually using the functions in your module.

I quickly realized that in that newer, AWS project, that I should’ve had some sort of automation create a scheduled task on my EC2 instances. What I wish had been automated was the regularly scheduled downloading of my main PowerShell module for these projects from S3 to the instances. A task such as this would keep me, or a coworker, from ever needing to manually update the PowerShell module on these instances again. Instead, a scheduled task would just download the module a few times a day, whether or not it had been updated. If it had, then suddenly my instances would have the newest functions, with no continued manual work on my part.

And, that led me to wonder, can I create a scheduled task on an instance when a PowerShell module is imported, as a part of the ScriptsToProcess .ps1, that can be set to run at the module import? That answer, is no.

Just kidding. It’s a yes! You can create a scheduled task on a computer the moment a PowerShell module is imported, thanks to ScriptsToProcess. There’s a bunch of parts and pieces to this, but what I’m going to include is the script file ScriptsToProcess executes, when my module imports.

# Create scheduled task, if able and necessary (admin).
If ([System.Boolean](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {

    $TaskName = 'EC2General PowerShell Module Update'
    If (-Not([System.Boolean](Get-ScheduledTask -TaskPath '\' -TaskName $TaskName -ErrorAction SilentlyContinue))) {
        $Command = "Import-Module -Name 'EC2General'; Update-EC2General"
        $Action = New-ScheduledTaskAction -Execute "$PSHOME\powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy ByPass -Command & {$Command}"
        $Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddDays(1).Date -RepetitionInterval (New-TimeSpan -Hours 1) -RepetitionDuration ([System.TimeSpan]::MaxValue)
        $Settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable -WakeToRun
        $Principal = New-ScheduledTaskPrincipal -UserID 'NT AUTHORITY\SYSTEM' -LogonType S4U -RunLevel Highest
        [System.Void](Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Settings $Settings -Principal $Principal)
    }
}

Neat stuff, right? What this code does is this. It begins by determining whether or not the user that’s importing the module is a local administrator, or not. They’re going to need to be, to register the scheduled task. If they are, and the task doesn’t already exist, it creates all the necessary variables to get the task created. When those are available, it’ll register the scheduled task.

I do want to credit Chrissy LeMaire, as a post of hers was used while I wrote the code necessary to create a scheduled task. There’s so much that goes into those, that I wasn’t going to trust myself to remember, or require myself to read the help files. I was confident she could be trusted.

This makes me wonder, though, what else should I do when a module loads?

Update: For our project, we didn’t actually use ScriptsToProcess. We did, however, manually run the code to create the task separately. It was that whole a-user-would-need-to-be-an-admin-problem, as most of my users weren’t admins. Keep that requirement in mind.

Leave a Reply

Your email address will not be published. Required fields are marked *