PowerShell: Creating Scheduled Tasks on Remote Servers

This script is deprecated. Here is a better iteration.

# scheduledTasksRemote_V0.0.2.ps1
# Purpose: to add a schedule onto remote system(s)
# Requires: PowerShell 3.0 or higher

# Scheduled task variables
$description="Daily snapshots of mounted volumes."

# Obtain Domain Admin Credentials
function obtainDomainAdminCredentials{
# Legacy domain binding function
function isValidCred($u,$p){
# Get current domain using logged-on user's credentials
$domain = "LDAP://" + ([ADSI]"").distinguishedName
$domainCred = New-Object System.DirectoryServices.DirectoryEntry($domain,$u,$p)
if ($domainCred){return $True}else{return $False}
function isDomainAdmin($username){
if (!(get-module activedirectory)){Install-WindowsFeature RSAT-AD-PowerShell -Confirm:$false}
if((Get-ADUser $username -Properties MemberOf).MemberOf -match 'Domain Admins'){return $True;}else{return $false;}

# Create a domain context
function dotNetDomainBind{
Add-Type -AssemblyName System.DirectoryServices.AccountManagement;
Try {
$type = [System.DirectoryServices.AccountManagement.ContextType]::Domain;
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $type,$env:USERDOMAIN;
return $context;
} Catch {
If ($_.Exception.InnerException -like "*The server could not be contacted*") {
write-host "Could not contact a server for the specified domain $env:USERDOMAIN via DotNet Method.";
} Else {
write-host "Unknown errors occured while attempting to contact $env:USERDOMAIN via DotNet Method.";
return $false;

$failureMessage = $null;

[string][ValidateNotNullOrEmpty()]$userName=Read-Host -Prompt "Please input a User ID";
if($userName -match '\\'){$username=$env:USERDOMAIN+'\'+$userName}
$password = Read-Host -Prompt "Please type in the password for user $userName" -AsSecureString;

# Test bind to this credential
try {
# Test bind
$validatedAccount = $context.ValidateCredentials($userName,$plainTextPassword)
$validatedAccount=isValidCred -u $userName -p $plainTextPassword

If ($validatedAccount) {
$isDomainAdmin=isDomainAdmin -username $userName;
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName,$password;
$failureMessage += "$attempt out of $maxAttempts`: $userName account is valid, but it is not a Domain Admin";
$failureMessage += "$attempt out of $maxAttempts`: username and/or password error";
$failureMessage += "Unable to bind to $env:USERDOMAIN.";

# Depending on whether there are failures, proceed accordingly
If ($attempt -lt $maxAttempts-1) {
$message = "$failureMessage`: Authentication error. Please Try again.";
Write-Warning $message;
} elseif ($attempt -eq $maxAttempts-1){
$message = "$failureMessage`: Last attempt.";
Write-Warning $message;
$credentials= $false;

} Until (($ValidAccount) -or ($Attempt -eq $MaxAttempts))
if($credentials){return $credentials;}else{return $false}

function isUnc($path){
$uncServer=$scriptFile | select-string -pattern "(?<=\\\\)(.*?)(?=\\)" | Select -ExpandProperty Matches | Select -ExpandProperty Value
$isValidPath=test-path $scriptfile -ErrorAction SilentlyContinue
if ($uncServer -and $isValidPath){
return $uncServer;
return $False;

function setScheduledTasks{

$uncServer=isUnc $scriptFile

if ($credential){
if ($uncServer){

foreach ($computer in $servers){
Invoke-Command -ComputerName $computer -Credential $credential -ScriptBlock{

$settingsCommand = New-ScheduledTaskSettingsSet -MultipleInstances IgnoreNew -ExecutionTimeLimit 0
$callPowerShell = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-ExecutionPolicy Bypass $scriptFile"
$dailyTrigger = New-ScheduledTaskTrigger -Daily -At 5pm

# Unrestrict this Domain Administrator from security prompts
Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted -Force

# Unblock file & Ensure that script exists
<# Overcome error caused by double hop issue:
Cannot find path '\\snapshots\FileServerClusters\Daily-VSS-Snapshot.ps1' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\snapshots\Fil...SS-Snapshot.ps1:String) [Unblock-File], ItemNotFoundException
+ FullyQualifiedErrorId : FileNotFound,Microsoft.PowerShell.Commands.UnblockFileCommand
+ PSComputerName : SHERVER007

1. Run scheduled task as: New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-ExecutionPolicy Bypass $scriptFile"
2. Unblock-File -Path $scriptFile
if ((Invoke-Command -computername $uncServer -Credential $Using:credential -ScriptBlock{Unblock-File -Path $Args[0];Test-Path $Args[0] -ErrorAction SilentlyContinue}-Args $scriptFile) -eq $False) {
"Errors locating $scriptFile... Skipping";

# Unregister the Scheduled task if it already exists
Get-ScheduledTask $taskName -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false;

# Create new scheduled task
Register-ScheduledTask -Action $callPowerShell -Trigger $dailyTrigger -TaskName $taskName -Description $description -User $username -Password $password -Settings $settingsCommand -RunLevel Highest;

} -ArgumentList $scriptFile,$taskName,$description,$username,$plainTextPassword,$uncServer
# pause;
"Need to run this program with a valid Domain Administrator account."

setScheduledTasks -servers $servers -scriptFile $scriptFile -description $description -taskName $taskName -credential $adminCredential

Leave a Reply

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