Archive | Scheduled tasks RSS for this section

Exporting all scheduled tasks

I wanted to have an export of all scheduled tasks ready for all servers that I manage, thus I created a little powershell tool that does that exactly.

It appeared to be pretty simple to reach this goal, as there is an Export-ScheduledTask function in Powershell.

This is what I used, but I wanted to have an export of all my scheduled tasks, without the default ones from Microsoft. So I needed to filter out a little bit.
There are two lines of code to filter out the unwanted tasks. First I removed the ones in the sub folder Microsoft and OfficeSoftwareProtection. After I run trough them to save the export (xml) of the task, I check if the task name doesn’t contain the text “User_Feed_Synchronization” or “Optimize Start Menu Cache Files”, if they aren’t called that, they’ll be exported.

(Get-ScheduledTask).TaskPath | Where { ($_ -notmatch "Microsoft") -and ($_ -notmatch "OfficeSoftware") } | Select -Unique
If(($TaskName -match "User_Feed_Synchronization") -or ($TaskName -match "Optimize Start Menu Cache Files"))

Troughout the running of the tool, it’ll output information to its log file. The files are saved in subdirectory names which correspond to the scheduled task folder they are found in.

This is the complete code for the tool:
$LogFile = "D:\Data\Logging\ExportScheduledTasks.log"
$BackupPath = "D:\Data\Tasks"
$TaskFolders = (Get-ScheduledTask).TaskPath | Where { ($_ -notmatch "Microsoft") -and ($_ -notmatch "OfficeSoftware") } | Select -Unique
Start-Transcript -Path $LogFile
Write-Output "Start exporting of scheduled tasks."

If(Test-Path -Path $BackupPath)
Remove-Item -Path $BackupPath -Recurse -Force
md $BackupPath | Out-Null

Foreach ($TaskFolder in $TaskFolders)
Write-Output "Task folder: $TaskFolder"
If($TaskFolder -ne "\") { md $BackupPath$TaskFolder | Out-Null }
$Tasks = Get-ScheduledTask -TaskPath $TaskFolder -ErrorAction SilentlyContinue
Foreach ($Task in $Tasks)
$TaskName = $Task.TaskName
If(($TaskName -match "User_Feed_Synchronization") -or ($TaskName -match "Optimize Start Menu Cache Files"))
$TaskInfo = Export-ScheduledTask -TaskName $TaskName -TaskPath $TaskFolder
$TaskInfo | Out-File "$BackupPath$TaskFolder$TaskName.xml"
Write-Output "Saved file $BackupPath$TaskFolder$TaskName.xml"

Write-Output "Exporting of scheduled tasks finished."

Create Windows scheduled task (for the NppUpdater script)

Create Windows scheduled task (for the NppUpdater script)

The previous NppUpdater script doesn’t do anything without it being scheduled in the task scheduler.

So I thought I also release a script to you, which does just that. If you add the code in this script to the NppUpdater script, it’ll also create the scheduled task if it doesn’t exist. Of course the script can also be used for scheduling other things.

The task is created with the following parameters:

  • The task’s created in a subfolder called “SysAdmins”
  • The task’s name is “NppUpdater”.
  • The task will start the NppUpdater.cmd file.
  • The task runs daily at 6 am, with a random start delay of 15 minutes
  • The task its start-in path is set to the path the script started from when it rain
  • The task will run with highest privileges as the account that ran it (which needs to be a member of the administrators group)
  • The task requires a logged on user (if you don’t prefer this: just change the script)

If you don’t want the text in your log file about the task already existing, change the line in the bottom from




The script can be found here: Create-ScheduledTask.ps1

Download SolarEdge solar production data and save to csv

I’ve got a nice solar panel setup on my roof, which uploads its data to the SolarEdge monitoring portal (this is the brand of inverter that I got). It appeared that this monitoring portal also has an API to automate getting the energy data. With me working in a company that works on energy savings, monitoring, consultancy etc, it’s a logical step for me to automate downloading the production of my panels, so my collueges at work can import this data in my energy monitoring portal at work and then they can do their magic calculations on them; which results in me getting nice graphs of my solar enrgy production.

The purpose of the tool:

I wrote this tool to be somewhat smart in what to download and what not. I only want to download the information if it’s up-to-date. Next to that, I’d want daily values, but also values with a 15 minute interval. In the end I’d want all the info to be exported to CSV files containing 1 month of data and/or 1 year of data. All files that have already been generated don’t need their data to be downloaded again and overwritten, thus it skips this data once it’s downloaded. In the end I can either mail these files or put them on a file share, so they can be imported by our energy monitoring system. This last step I’ve removed from the script that I share with you.

Several nice ‘techniques’ used in this script to get to the goal:

Since I’m talking with an API, the main important command is the Invoke-WebRequest with a pipe to ConvertFrom-Json

To get the last day of the month, the following line is used: $LastDayOfTheMonth = ((Get-Date -Date “01-$Month-$Year” -Hour 0 -Minute 0 -Second 0).AddMonths(1).AddSeconds(-1)).Day

(which will add a month to the date/time 01-<month>-<year> : 0:00 and then remove 1 second to get to the last second of the previous month, thus resulting in returning the last day of that month (<last day>-<month>-<year> 23:59:59))

In the end, the downloaded data is converted to CSV with this command: | ConvertTo-Csv -Delimiter “;” -NoTypeInformation (in Excel with localization the Netherlands, the semicolon is a better seperator than a comma, since Excel expects a semicolon. This saves me time on opening the csv files and converting the information to an excel readable file. Depending on your localization settings, you’d want to change this accordingly) I also add the switch -NoTypeInformation, since I’m not interested in getting information about the type of variable PS used, I only need the data.

Script parameters and bounds:

The script will check the solaredge portal for the date/time on which the installation received its latest data. If this date is not the same as today, something might be wrong. It’ll warn you about it, but will still download. If it’s out of date for more than 1 day, it’ll give an error about this, but the script will still continue. When no data has been downloaded, the tool will download all data (starting on the installation date of the inverter) per month and save these to csv files. It will also generate files with yearly data. The data that’s downloaded is from the previous month (unless this is a later date than the date the last data was received on the solaredge monitoring portal, then the last data date will be used). In case of the daily values (monthly and yearly csv’s), the tool will only store the value’s if they’re not $null (which is: no data received on portal or the solar panels with its optimizers as a whole aren’t yet initialized by the inverter). In case of the 15 minute interval values, all $null values will be replaced by 0,0 (in that case the inverter is turned off because of its night mode); thus giving a nice list of 96 readings each day, and resulting in about 2688 – 2976 values in each file, depending on the amount of days in the month (which can be checked for, if needed; in my case I don’t, since my work already has many comprehensive tools to check for gaps or strange behaviour in data).

The script can be found and downloaded here: DownloadEnergyData.ps1


Edit: I got myself an undocumented API call parameter from a SolarEdge developer, which gives me 15 minute values in WH 🙂 The script has been updated. (&TimeUnit=QUARTER_OF_AN_HOUR)

Net stop/start W3SVC and Stop/Start-Service W3SVC vs IISREST STOP/START

I encountered a problem where I wanted to stop and start IIS by using either the command line or powershell versions of stopping and starting IIS.

Stop-Service W3SVC
Start-Service W3SVC

Both of those stopped and started the World Wide Publishing service correctly. But both appeared to not stop/recycle the worker processes. With Net start and stop giving an error message when IIS was already stopped and/or started before running those commands, resulting in a scheduled task error code.

I found that using the IISRESET command, it does close those worker processes and when IIS was already stopped and/or started it didn’t return an error, thus resulting in the scheduled task returning a nice 0x0 (success)

Thus: use the following commands (also within powershell) if you want to stop/start IIS websites. This will always work as intended and not return an error code (in some cases, where the others would)


Get all (non-default) scheduled tasks

I tried querying the scheduled tasks to give me a list of all (non-default) scheduled tasks. I also wanted to have its schedule information, which appeared to be a pretty hard task in the get-service command. After several unsuccessful attempts, I tried something else with great and immediate results. It appeared that the schtasks did give me all the info I need, so I query the tasks by using the schtasks dos tool and saving that information into variables.

Since all default tasks either have no computername, no author, next run time as N/A, or contains the author Microsoft. So first I will query for all scheduled tasks and then filter out those that I don’t need; thus leaving me with the tasks I need for my automatic documentation purposes.

I haven’t tested the script on Windows 2008, but I assume that it uses the same naming as Windows 2012; the commands itself are all Powershell 2 compatible, so should work on 2008 as they also work on Windows 2003.

In this script I don’t remove disabled tasks from the list, because I need to list those myself as well, but I did supply the line that you can add to the where-object part of the $ScheduledTasks to filter those out as well.

The text for every schedule was returned over several properties, of which I make a readable (pretty plain English) text at both Switch parts of the script (one for Windows 2003, the other for 2012 (and presumably 2008)). Beware of the spaces after Daily and Hourly, which schtasks appears to return!


#Get all scheduled tasks on the system in a Csv format
$Tasks = schtasks /query /v /fo csv | ConvertFrom-Csv
#Filtering out all Windows tasks for Windows 2k3 and 2k12 (and 2k8?)
$ScheduledTasks = $Tasks | Where-Object { $_.HostName -eq $env:COMPUTERNAME -and $_.Author -ne "N/A" -and $_.'Next Run Time' -ne "N/A" -and $_.Author -notmatch "Microsoft" -and $_.TaskName -notmatch "User_Feed_Synchronization" }
# -and $_.'Scheduled Task State' -ne "Disabled" # <-- Add this to the where-object selection in the line above to filter out disabled tasks as well

Foreach($ScheduledTask in $ScheduledTasks)
$Tasktext = ""
$ScheduledTask.'Start In'
$ScheduledTask.'Task To Run'
#In case of W2k12 (and W2k8?)
If($ScheduledTask.'Schedule Type')
Switch($ScheduledTask.'Schedule Type')
"Hourly " { $Tasktext = $ScheduledTask.'Schedule Type' + "at " + $ScheduledTask.'Start Time' }
"Daily " { $Tasktext = $ScheduledTask.'Schedule Type' + "at " + $ScheduledTask.'Start Time' }
"Weekly" { $Tasktext = $ScheduledTask.'Schedule Type' + " on every " + $ScheduledTask.Days + " at " + $ScheduledTask.'Start Time' }
If($ScheduledTask.Months -eq "Every month") { $Tasktext = $ScheduledTask.'Schedule Type' + " on day " + $ScheduledTask.Days + " at " + $ScheduledTask.'Start Time'}
Else { $Tasktext = "Yearly on day " + $ScheduledTask.Days + " of " + $ScheduledTask.Months + " at " + $ScheduledTask.'Start Time' }
#In case of W2k3
If($ScheduledTask.'Scheduled Type')
Switch($ScheduledTask.'Scheduled Type')
"Hourly " { $Tasktext = $ScheduledTask.'Scheduled Type' + "at " + $ScheduledTask.'Start Time' }
"Daily " { $Tasktext = $ScheduledTask.'Scheduled Type' + "at " + $ScheduledTask.'Start Time' }
"Weekly" { $Tasktext = $ScheduledTask.'Scheduled Type' + " on every " + $ScheduledTask.Days + " at " + $ScheduledTask.'Start Time' }
If($ScheduledTask.Months -eq "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC") { $Tasktext = $ScheduledTask.'Scheduled Type' + " on day " + $ScheduledTask.Days + " at " + $ScheduledTask.'Start Time' }
Else { $Tasktext = "Yearly on day " + $ScheduledTask.Days + " of " + $ScheduledTask.Months + " at " + $ScheduledTask.'Start Time' }
#This line can be removed if the filter excludes disabled tasks
If($ScheduledTask.'Scheduled Task State' -eq "Disabled") { $Tasktext = "Disabled" }

This leave you with the following 4 variables, which you can use for exporting or other purposes

$ScheduledTask.'Start In'
$ScheduledTask.'Task To Run'

You can download a copy of this script from my skydrive