Last active
February 9, 2017 20:44
-
-
Save mhudasch/da144c79fbb240b8f45979a3ec1eb4e9 to your computer and use it in GitHub Desktop.
Invoke a command via the task scheduler on any computer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 5 | |
Set-StrictMode -Version Latest | |
Function Invoke-ScheduledCommand { | |
[Diagnostics.CodeAnalysis.SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "", Justification = "This re-establishes the global environment preferences. They can be used all over child scripts.")] | |
[OutputType("ScheduledCommandResult[]")] | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory=$true,Position=0)] | |
[String]$TaskName, | |
[Parameter(Mandatory=$true,Position=1)] | |
[ScriptBlock]$ScriptBlock, | |
[Parameter(Mandatory=$false,Position=2)] | |
[object[]]$ArgumentList, | |
[Parameter(Mandatory=$false,Position=3)] | |
[String[]]$ComputerName = $env:COMPUTERNAME, | |
[Parameter(Mandatory=$false,Position=4)] | |
[pscredential]$Credential, | |
[Parameter(Mandatory=$false,Position=5)] | |
[pscredential]$TaskCredential, | |
[Parameter(Mandatory=$false,Position=6)] | |
[Switch]$Elevated, | |
[Parameter(Mandatory=$false,Position=7)] | |
[Switch]$Interactive, | |
[Parameter(Mandatory=$false,Position=8)] | |
[Switch]$AsJob) | |
Process { | |
$block = [scriptblock] { | |
param($tn, $sc, $scargs, $cn, [pscredential]$cred, [pscredential]$tcred, $elev, $inter, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | |
$VerbosePreference = $vpref; | |
$ErrorActionPreference = $erpref; | |
$WarningPreference = $wpref; | |
$DebugPreference = $dpref; | |
$InformationPreference = $ipref; | |
$registerBlock = [scriptblock] { | |
param($tn, $sc, $scargs, $elev, $inter, [pscredential]$tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | |
$ModuleLogLocationPreference = $llpref; | |
$ModuleScriptLocationPreference = $scpref; | |
$VerbosePreference = $vpref; | |
$ErrorActionPreference = $erpref; | |
$WarningPreference = $wpref; | |
$DebugPreference = $dpref; | |
$InformationPreference = $ipref; | |
if(!(Get-Command -Name Write-LogFile -ErrorAction SilentlyContinue)) { | |
# remap the passed logging function script | |
New-Item -Path function: -Name 'Write-LogFile' -Value $logsc | Out-Null; | |
} | |
if(!(Test-Path $llpref)) { New-Item -ItemType Directory -Path $llpref -Force | Out-Null; } | |
if(!(Test-Path $scpref)) { New-Item -ItemType Directory -Path $scpref -Force | Out-Null; } | |
$result = @{ | |
ScriptName=$null; | |
ScriptPath=$null; | |
ScriptLog=$null; | |
ScriptReturn=$null; | |
ComputerName=$null; | |
Script=$null; | |
TaskDefinition=$null; | |
EndState=$null; | |
LastRunTime=$null; | |
ReturnCode=$null; | |
Out=$null; | |
Error=$null; | |
Warning=$null; | |
Verbose=$null; | |
Debug=$null; | |
Information=$null; | |
}; | |
$result.ComputerName = $env:ComputerName; | |
$path = Join-Path $scpref ($tn + ".cmd"); | |
$scrPath = Join-Path $scpref ($tn + ".ps1"); | |
$logPath = Join-Path $llpref ($tn + ".log"); | |
$outPath = Join-Path $scpref($tn + ".out"); | |
$errPath = Join-Path $scpref($tn + ".err"); | |
$vrbPath = Join-Path $scpref($tn + ".vrb"); | |
$wrnPath = Join-Path $scpref($tn + ".wrn"); | |
$dbgPath = Join-Path $scpref($tn + ".dbg"); | |
$infoPath = Join-Path $scpref($tn + ".info"); | |
if(!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")){ | |
$ex = New-Object 'AccessViolationException' -ArgumentList "You must be in an Administrator role on the target computer to access the task scheduler there.", $null; | |
$result.Error = New-Object System.Management.Automation.ErrorRecord -ArgumentList $ex, "0", "SecurityError", $tn; | |
$result = New-Object -TypeName psobject -Property $result; | |
$result.psobject.typenames.Insert(0, "ScheduledCommandResult"); | |
$result | Write-Output; | |
return; | |
} | |
#$TASK_STATE_UNKNOWN = 0; | |
#$TASK_STATE_DISABLED = 1; | |
$TASK_STATE_QUEUED = 2; | |
# $TASK_STATE_READY = 3; | |
$TASK_STATE_RUNNING = 4; | |
$serializeObjectDepth = 10; | |
("".PadRight(100,"=")) | Write-LogFile -Name $tn | Out-Null; | |
"[$env:ComputerName] Script-Name: '$tn'." | Write-LogFile -Name $tn | Write-Verbose; | |
"[$env:ComputerName] Script-Path: '$path'." | Write-LogFile -Name $tn | Write-Verbose; | |
"[$env:ComputerName] Script-Log: '$logPath'." | Write-LogFile -Name $tn | Write-Verbose; | |
"[$env:ComputerName] Script-Return: '$outPath'." | Write-LogFile -Name $tn | Write-Verbose; | |
$result.ScriptName = $tn; | |
$result.ScriptPath = $path; | |
$result.ScriptLog = $logPath; | |
$result.ScriptReturn = $outPath; | |
#region wrapper script build | |
$wlog = $logsc.Replace('"$ModuleLogLocationPreference"', "`"$llpref`"").Replace("-NoNewline", "").Replace('$', '`$'); | |
$scPreamble = "`$VerbosePreference = '$vpref';`r`n"; | |
$scPreamble += "`$ErrorActionPreference = '$erpref';`r`n"; | |
$scPreamble += "`$WarningPreference = '$wpref';`r`n"; | |
$scPreamble += "`$DebugPreference = '$dpref';`r`n"; | |
$scPreamble += "`$InformationPreference = '$ipref';`r`n"; | |
$scPreamble += "`$script:ScheduledCommandName=`"$tn`";`r`n"; | |
$scPreamble += "`$script:ScheduledCommandLogPath=`"$logPath`";`r`n"; | |
$scPreamble += "`$script:PostponeAutoCleanup=`$false;`r`n"; | |
$scPreamble += "if(!(Get-Command `"Write-LogFile`" -ErrorAction Ignore)) { New-Item -Path 'function:' -Name 'Write-LogFile' -Value `@`"`r`n$wlog`r`n`"`@ | Out-Null; }`r`n" | |
$scPreamble += "`$scwarn=@(); `$scverbose=@(); `$scdebug=@(); `$scinfo=@();`r`n"; | |
$scArgumentStatement = "-ArgumentList `$([System.Management.Automation.PSSerializer]::Deserialize(@`"`r`n$([System.Management.Automation.PSSerializer]::Serialize($scargs, 999))`r`n`"@))"; | |
if($scargs) { | |
$scInvokation = "`r`n`(Invoke-Command -ScriptBlock { $sc } -ErrorAction Stop -ErrorVariable scerr $scArgumentStatement 3>&1 4>&1 5>&1 6>&1) | `r`n"; | |
} else { | |
$scInvokation = "`r`n`(Invoke-Command -ScriptBlock { $sc } -ErrorAction Stop -ErrorVariable scerr 3>&1 4>&1 5>&1 6>&1) | `r`n"; | |
} | |
$scStreamfilter = "ForEach-Object { `$t = `$_.GetType().Name; `$item = `$_; switch (`$t) { `"WarningRecord`" { `$scwarn+=`$item; } `"VerboseRecord`" { `$scverbose+=`$item; } `"DebugRecord`" { `$scdebug+=`$item; } `"InformationRecord`" { `$scinfo+=`$item; } default { `$item; } } } | "; | |
$scOutPipe = "Export-CliXml -Path `"$outPath`" -Depth $serializeObjectDepth -Force;`r`n"; | |
$scErrPipe = "if(`$scerr) { `$scerr | Export-CliXml -Path `"$errPath`" -Depth $serializeObjectDepth -Force; }`r`n"; | |
$scVrbPipe = "if(`$scverbose.Count -gt 0) { `$scverbose | Export-CliXml -Path `"$vrbPath`" -Depth $serializeObjectDepth -Force; }`r`n"; | |
$scWrnPipe = "if(`$scwarn.Count -gt 0) { `$scwarn | Export-CliXml -Path `"$wrnPath`" -Depth $serializeObjectDepth -Force; }`r`n"; | |
$scDbgPipe = "if(`$scdebug.Count -gt 0) { `$scdebug | Export-CliXml -Path `"$dbgPath`" -Depth $serializeObjectDepth -Force; }`r`n"; | |
$scInfoPipe = "if(`$scinfo.Count -gt 0) { `$scinfo | Export-CliXml -Path `"$infoPath`" -Depth $serializeObjectDepth -Force; }`r`n"; | |
$finalScript = "$scPreamble try { $scInvokation $scStreamfilter $scOutPipe $scErrPipe $scVrbPipe $scWrnPipe $scDbgPipe $scInfoPipe } catch [System.Exception] { `$(`$_.Exception | Format-List -Force | Out-String) | Out-File `"$logPath`" -Append -Encoding utf8; `$_.Exception | Export-CliXml -Path `"$errPath`" -Depth $serializeObjectDepth -Force; } "; | |
$result.Script = $finalScript; | |
#endregion | |
Set-Content -Path $scrPath -Value $finalScript -Encoding UTF8 -Force | Out-Null; | |
$cmd = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File $scrPath"; | |
Set-Content -Path $path -Value $cmd -Encoding Ascii -Force | Out-Null; | |
$taskTemplate = "<?xml version=`"1.0`" encoding=`"UTF-16`"?><Task version=`"1.2`" xmlns=`"http://schemas.microsoft.com/windows/2004/02/mit/task`"><RegistrationInfo><Author>_AUTHOR_</Author><Description>_TASKNAME_</Description></RegistrationInfo><Triggers /><Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>true</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable><IdleSettings><Duration>PT10M</Duration><WaitTimeout>PT1H</WaitTimeout><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>PT72H</ExecutionTimeLimit><Priority>7</Priority></Settings><Actions Context=`"Author`"><Exec><Command>_COMMAND_</Command></Exec></Actions><Principals><Principal id=`"Author`"><UserId>_TASKUSER_</UserId><LogonType>_LOGONTYPE_</LogonType><RunLevel>_RUNLEVEL_</RunLevel></Principal></Principals></Task>"; | |
$taskTemplate = $taskTemplate -replace "_AUTHOR_", $([Security.Principal.WindowsIdentity]::GetCurrent().Name); | |
$taskTemplate = $taskTemplate -replace "_TASKNAME_", $tn; | |
$taskTemplate = $taskTemplate -replace "_COMMAND_", $path; | |
if($null -ne $tcred) { | |
$taskCredUserName = $tcred.UserName; | |
$taskTemplate = $taskTemplate -replace "_TASKUSER_", $taskCredUserName; | |
} else { | |
$taskTemplate = $taskTemplate -replace "_TASKUSER_", "SYSTEM"; | |
} | |
if($elev) { | |
$taskTemplate = $taskTemplate -replace "_RUNLEVEL_", "HighestAvailable"; | |
} else { | |
$taskTemplate = $taskTemplate -replace "_RUNLEVEL_", "LeastPrivilege"; | |
} | |
if($inter) { | |
$taskTemplate = $taskTemplate -replace "_LOGONTYPE_", "InteractiveToken"; | |
} else { | |
$taskTemplate = $taskTemplate -replace "_LOGONTYPE_", "Password"; | |
} | |
$result.TaskDefinition = $taskTemplate; | |
$scheduler = New-Object -ComObject Schedule.Service; | |
"[$env:ComputerName] Connect to scheduler and register task." | Write-LogFile -Name $tn | Write-Verbose; | |
for ($i=1; $i -le 3; $i++) { | |
Try { | |
$scheduler.Connect(); | |
"[$env:ComputerName] OK" | Write-LogFile -Name $tn | Write-Verbose; | |
Break; | |
} Catch { | |
if($i -ge 3) { | |
"[$env:ComputerName] Can't connect to Schedule service." | Write-LogFile -Name $tn | Write-Error -ErrorAction Stop | |
} else { | |
Start-Sleep -Seconds 1; | |
} | |
} | |
} | |
$task = $scheduler.NewTask($null); | |
$task.XmlText = $taskTemplate; | |
$rootFolder = $scheduler.GetFolder("\"); | |
if($tcred) { | |
$taskCredUserName = $tcred.UserName; | |
$taskCredPasswordClear = $tcred.GetNetworkCredential().Password; | |
if($inter) { | |
$td = ($rootFolder.RegisterTaskDefinition($tn, $task, 6, $taskCredUserName, $Null, 3) | Out-String); | |
} else { | |
$td = ($rootFolder.RegisterTaskDefinition($tn, $task, 6, $taskCredUserName, $taskCredPasswordClear, 1) | Out-String); | |
} | |
} else { | |
$td = ($rootFolder.RegisterTaskDefinition($tn, $task, 6, "SYSTEM", $Null, 1) | Out-String); | |
} | |
$td | Write-LogFile -Name $tn | Out-Null; | |
"[$env:ComputerName] Task $tn added to scheduler." | Write-LogFile -Name $tn | Write-Verbose; | |
"[$env:ComputerName] Running the task $tn in the scheduler." | Write-LogFile -Name $tn | Write-Verbose; | |
$r = ($rootFolder.GetTask($tn).Run(0) | Out-String); | |
if($r) { $r | Write-LogFile -Name $tn | Write-Verbose; } | |
# wait unil it is started | |
do { | |
Start-Sleep -Seconds 1; | |
$taskInstance = $rootFolder.GetTask($tn); | |
if($taskInstance.State -eq $TASK_STATE_QUEUED) { | |
"[$env:ComputerName] Still waiting for task $tn to start..." | Write-LogFile -Name $tn | Write-Verbose; | |
} else { | |
"[$env:ComputerName] Task $tn is started." | Write-LogFile -Name $tn | Write-Verbose; | |
break; | |
} | |
} while($true); | |
# wait until is finished | |
do { | |
$taskInstance = $rootFolder.GetTask($tn); | |
if($taskInstance.State -eq $TASK_STATE_RUNNING) { | |
"[$env:ComputerName] Task $tn is still running..." | Write-LogFile -Name $tn | Write-Verbose; | |
} else { | |
$result.EndState = $taskInstance.State; | |
$result.LastRunTime = $taskInstance.LastRunTime; | |
$result.ReturnCode = $taskInstance.LastTaskResult; | |
"[$env:ComputerName] Task $tn is done. (with state: $($taskInstance.State) - last run time: $($taskInstance.LastRunTime) - last task result: $($taskInstance.LastTaskResult))" | Write-LogFile -Name $tn | Write-Verbose; | |
break; | |
} | |
Start-Sleep -Seconds 5; | |
} while($true); | |
if(Test-Path $outPath) { | |
$result.Out = Import-Clixml -Path $outPath; | |
if($null -eq $result.ReturnValue) { "[$env:ComputerName] Scheduled task $tn returned nothing." | Write-LogFile -Name $tn | Write-Verbose; } | |
else { "[$env:ComputerName] Scheduled task $tn has returned something." | Write-LogFile -Name $tn | Write-Verbose; } | |
"[$env:ComputerName] Removing out file of task $tn." | Write-LogFile -Name $tn | Write-Verbose; | |
Remove-Item $outPath -Force | Out-Null; | |
"[$env:ComputerName] OK" | Write-LogFile -Name $tn | Write-Verbose; | |
} else { | |
"[$env:ComputerName] Scheduled task $tn returned nothing." | Write-LogFile -Name $tn | Write-Verbose; | |
} | |
if(Test-Path $errPath) { | |
$result.Error = Import-Clixml -Path $errPath; | |
if($null -ne $result.Error) { "[$env:ComputerName] Scheduled task $tn resulted in an error." | Write-LogFile -Name $tn | Write-Verbose; } | |
"[$env:ComputerName] Removing err file of task $tn." | Write-LogFile -Name $tn | Write-Verbose; | |
Remove-Item $errPath -Force | Out-Null; | |
"[$env:ComputerName] OK" | Write-LogFile -Name $tn | Write-Verbose; | |
} | |
if(Test-Path $vrbPath) { | |
$result.Verbose = Import-Clixml -Path $vrbPath; | |
Remove-Item $vrbPath -Force | Out-Null; | |
} | |
if(Test-Path $wrnPath) { | |
$result.Warning = Import-Clixml -Path $wrnPath; | |
Remove-Item $wrnPath -Force | Out-Null; | |
} | |
if(Test-Path $dbgPath) { | |
$result.Debug = Import-Clixml -Path $dbgPath; | |
Remove-Item $dbgPath -Force | Out-Null; | |
} | |
if(Test-Path $infoPath) { | |
$result.Information = Import-Clixml -Path $infoPath; | |
Remove-Item $infoPath -Force | Out-Null; | |
} | |
"[$env:ComputerName] Removing the task $tn out of the scheduler." | Write-LogFile -Name $tn | Write-Verbose; | |
$r = $rootFolder.DeleteTask($tn,0); | |
if($r) { $r | Write-LogFile -Name $tn | Write-Verbose; } | |
"[$env:ComputerName] OK" | Write-LogFile -Name $tn | Write-Verbose; | |
"[$env:ComputerName] Removing the script file ('$path', '$scrPath')." | Write-LogFile -Name $tn | Write-Verbose; | |
Remove-Item $path -Force | Out-Null; | |
Remove-Item $scrPath -Force | Out-Null; | |
"[$env:ComputerName] OK" | Write-LogFile -Name $tn | Write-Verbose; | |
$result = New-Object -TypeName psobject -Property $result; | |
$result.psobject.typenames.Insert(0, "ScheduledCommandResult"); | |
$result | Write-Output; | |
}; | |
if($env:COMPUTERNAME -eq $cn) { # locally | |
if($null -eq $cred) { | |
Invoke-Command -ScriptBlock $registerBlock -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | Write-Output; | |
} else { | |
Invoke-Command -Credential $cred -ScriptBlock $registerBlock -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | Write-Output; | |
} | |
} else { #remotely | |
$list = New-Object System.Collections.ArrayList; | |
$list.AddRange(@($cn)); $l = $false; | |
if($list -icontains $env:COMPUTERNAME) { $l = $true; $ln = New-Object System.Collections.ArrayList; $ln.AddRange(@($list | Where-Object { $_ -inotmatch $env:COMPUTERNAME })); $list = $ln; } | |
if($l) { | |
if($null -eq $cred) { | |
Invoke-Command -ScriptBlock $registerBlock -HideComputerName -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | ForEach-Object { | |
$_.psobject.typenames.Insert(0, "ScheduledCommandResult"); $_; } | Write-Output; | |
} else { | |
Invoke-Command -Credential $cred -ScriptBlock $registerBlock -HideComputerName -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | ForEach-Object { | |
$_.psobject.typenames.Insert(0, "ScheduledCommandResult"); $_; } | Write-Output; | |
} | |
} | |
if($null -eq $cred) { | |
Invoke-Command -ComputerName ($list.ToArray()) -ScriptBlock $registerBlock -HideComputerName -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | ForEach-Object { | |
$_.psobject.typenames.Insert(0, "ScheduledCommandResult"); $_; } | Write-Output; | |
} else { | |
Invoke-Command -ComputerName ($list.ToArray()) -Credential $cred -ScriptBlock $registerBlock -HideComputerName -ArgumentList @($tn, $sc, $scargs, $elev, $inter, $tcred, $logsc, $llpref, $scpref, $erpref, $vpref, $wpref, $dpref, $ipref) | ForEach-Object { | |
$_.psobject.typenames.Insert(0, "ScheduledCommandResult"); $_; } | Write-Output; | |
} | |
} | |
}; | |
# normally this variable comes from a sorrounding module | |
# but when it is not there... | |
if(-not(Get-Variable -Name "ModuleLogLocationPreference" -ErrorAction Ignore)) { | |
$ModuleLogLocationPreference = 'C:\Users\Public' | |
$ModuleScriptLocationPreference = 'C:\Users\Public' | |
} | |
# normally this function comes from a sorrounding module | |
# but when it is not there... | |
if(-not(${function:Write-LogFile})) { | |
Function Write-LogFile { | |
param( | |
[Parameter(Mandatory=$true,Position=0, ValueFromPipeline=$true, ParameterSetName="IO")] | |
[object[]]$InputObject, | |
[Parameter(Mandatory=$true,Position=0, ParameterSetName="Message")] | |
[AllowEmptyString()] | |
[string]$Message, | |
[Parameter(Mandatory=$false, ParameterSetName="Message")] | |
[Switch]$PassThru, | |
[Parameter(Mandatory=$false,Position=1)] | |
[string]$Name = "log_$([datetime]::Now.ToString("yyyy-MM-dd"))", | |
[Parameter(Mandatory=$false,Position=2)] | |
[string]$Path = "$ModuleLogLocationPreference" | |
) | |
Process { | |
$pre = [datetime]::Now.ToString("[yyyy-MM-dd HH:mm:ss.fff]"); | |
$llp = "$Path\$Name.log"; | |
switch ($PSCmdlet.ParameterSetName) { | |
"IO" { | |
$InputObject | ForEach-Object { ("{0} {1}" -f $pre, $($_ | Format-List * | Out-String)) | Out-File $llp -Encoding utf8 -Append -NoNewline; $_ } | Write-Output; | |
} | |
"Message" { | |
if($PassThru.IsPresent) { | |
$Message | ForEach-Object { ("{0} {1}" -f $pre, $_) | Out-File $llp -Encoding utf8 -Append; $_ } | Write-Output; | |
} else { | |
$Message | ForEach-Object { ("{0} {1}" -f $pre, $_) | Out-File $llp -Encoding utf8 -Append; }; | |
} | |
} | |
} | |
} | |
} | |
} | |
if($AsJob.IsPresent) { | |
Start-Job -Name $TaskName -ScriptBlock $block -ArgumentList @($TaskName, $ScriptBlock, $ArgumentList, $ComputerName, $Credential, $TaskCredential, $Elevated, $Interactive, ${function:Write-LogFile}.ToString(), $ModuleLogLocationPreference, $ModuleScriptLocationPreference, $ErrorActionPreference, $VerbosePreference, $WarningPreference, $DebugPreference, $InformationPreference) | Write-Output; | |
} else { | |
Invoke-Command -ScriptBlock $block -ArgumentList @($TaskName, $ScriptBlock, $ArgumentList, $ComputerName, $Credential, $TaskCredential, $Elevated, $Interactive, ${function:Write-LogFile}.ToString(), $ModuleLogLocationPreference, $ModuleScriptLocationPreference, $ErrorActionPreference, $VerbosePreference, $WarningPreference, $DebugPreference, $InformationPreference) | Write-Output; | |
} | |
} | |
} | |
Update-TypeData -TypeName "ScheduledCommandResult" -DefaultDisplayPropertySet "ScriptName","ScriptPath","ScriptLog","ScriptReturn","ComputerName","EndState","LastRunTime","ReturnCode","Out","Error","Warning","Verbose","Debug","Information" -Force; | |
Update-TypeData -TypeName "ScheduledCommandResult" -DefaultKeyPropertySet "ScriptName","ComputerName" -Force; |
This should be fixed now. The problem was that I use this script in context of a powershell module and not stand-alone. Some of the variables are not set when it is used stand-alone. Now this variables are initialized correctly.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sadly your function doesn't work for me.. No matter which parameters I always get:
You know how to solve this? Many thanks
You cannot call a method on a null-valued expression.
At C:\temp\Invoke-ScheduledCommand.ps1:295 char:7