Frank Detzer



tl;dr - download @

This cmdlet was quite the journey to begin with. I started to do a lot of IFTTT (If This Then That) with my iPhone. Inspired by that I started writing extremely specific Power Shell functions on my PC that would be triggered by the task scheduler. Enabling me to do tedious tasks amazingly comfortable. With that in mind and me loving to use Power Shell I quickly came across the fact that there is not an option to copy a scheduled task. That said this was not anything new, but it became frustrating if you have a task that utilize a lot of functions.

So, I fired up Visual Studio Code and made this little supplement Cmdlet “Copy-ScheduledTask”. The heavy workload is being done by 3 Components, the destination-component, the amount-of-copies component and the register-component, that does the heavy work.

The destination-component mainly focuses on the $URI-variable that is piped on be the “Get-ScheduledTask” Cmdlet. Using a parameter that is bound to a “ValueFromPipelineByPropertyName” of a Microsoft written Cmdlet was something very new for me. If you receive data from another cmdlet you can build a psobject or process the data with that for every object, the previous Cmdlets sends over the pipe. There I learned that you need to do this with a foreach-loop, which I really did not expect since thought that one Cmdlet finishes and sends the whole workload to the next one. You learn something new every day 😊. At the beginning my function would not rely on another Cmdlet but that really blew the KISS-principle I try to base my functions on. Earlier versions would require code that prepares the data just to display it to the user and then make the user choose the function that the user want to create a copy of. I completely abandoned that approach since the user would do that anyway, nobody just decided to copy something that is unknown to them so making the user do that a second time would be a waste to time.

These Read-Host Cmdlets really blew it out of proportion.

What I did not expect was that I would spend the most time with the component that is responsible for the naming of the task. Everybody created so many copies of so many files and nobody would ever think of how the program would handle it if you do not want to replace the file. Well just add a counter to the end, simple as that right. But the counter is an integer value, and the rest is a string value. So, what If the last character of the string is not the actual counter that you could easily convert to an integer, so you cannot just read the old name take the last character and add +1 to it. So, a simple thing turns out to something that there is way more to it. I coded the function in a way that if you copy a task to another location it does not rename it at all and if you do create a copy in the same location it adds simply “– copy” to it. If you request the function to create multiple copies, there comes the counter into play. At first, I run it in a nested foreach-loop but loved the do-until-loop at the end way more, so ended up using that for the first time.

The actual heavy work is being done by the “Register-ScheduledTask” Cmdlet Microsoft provides. So, what “Copy-ScheduledTask” actually does is making it really easy and wiring everything up in a way that only requires you to pipe what you selected from “Get-ScheduledTask”. This makes “Copy-ScheduledTask” what I would call a “supplement Cmdlet”. If you want you can create multiple copies, rename the copies, deactivate the copies (mainly that backed up tasks do not run multiple times) and delete the source task.

In the end I loved making this Cmdlet because it gave me the opportunity to learn a lot about the pipe, using the do-until-loop and making life easier and what is more rewarding than that 😊. When doing my research, I have found this How-to on by Mauro Huculak which helped me out a lot (scroll down to find the Power Shell part). Also, big thanks to June Blender on, who explained how to handle receiving input from the pipeline very well.

You can download the function @ Github

Prev post