Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to remotely create a scheduled task and folder.
Microsoft Scripting Guy, Ed Wilson, is here. On Friday in Use PowerShell to Create Scheduled Task in New Folder, I created a pretty long Windows PowerShell script that creates a folder for scheduled tasks, and creates, enables, and configures a scheduled task.
Over the weekend, I received several emails to scripter@microsoft.com that said basically, “That is all good, but I need to create the same scheduled task on a hundred servers. I cannot run around to run this script on all of them.”
Dude (or dudette), this is actually pretty easy because since Windows PowerShell 2.0, Windows PowerShell has had remoting built in. In fact, the server version of the operating system has Windows PowerShell remoting enabled by default.
I do not even need to write a script to run a script. I can do this in one line. Here is that line of code (I could make the command a bit shorter by using aliases and a positional parameter, but it would be even harder to read than it is now):
Invoke-Command -ComputerName (Get-ADComputer -filter * -SearchBase 'ou=servers,dc=nwtraders,dc=com').name -FilePath C:\fso\CreateScheduledTaskFolderAndTask.ps1
So what I decided to do was to write a short script that would do this configuration for me…
The first thing I do is create my search base string. This specifies the organizational unit that I will query. Because I only want these scheduled tasks to be on servers (not on domain controllers or workstations), I query an organizational unit called servers. Here is my search base:
$searchBase = "ou=servers,dc=nwtraders,dc=com"
Next I need to specify the path to the script. The cool thing is the script does not need to exist on the remote servers. It does not need to exist on a share. It can exist on my workstation. What happens is that Windows PowerShell reads the script file and converts the script into a script block. Then it executes that script block on the remote servers. So I only need a path that is accessible to my workstation. For this, I use my ubiquitous scratch folder named FSO. Here is the path to my script:
$filepath = "C:\fso\CreateScheduledTaskFolderAndTask.ps1"
Note The script I am executing is the exact script I wrote on Friday. I have not modified it in any way.
I use the Get-ADComputer cmdlet to query for all the computers in the servers organizational unit. Here is that line of code:
$cn = Get-ADComputer -Filter * -SearchBase $searchBase
Note The Get-ADComputer cmdlet is available from the Active Directory module. I obtained the Active Directory
module on my workstation when I installed the Remote Server Administration Tools (RSAT). Versions of RSAT are
operating system specific.
Now I walk through the collection of computer objects stored in the $cn variable, and I test my WinRm connection to the remote machine before I try to run the script. There is a Test-Connection cmdlet that sends a ping. The problem is that by default, ICMP packets are filtered in Windows Firewall; therefore, ping commands will fail. But I wanted to ensure that the remote computer was up and responding, so I use Test-WsMan instead. Here is that command:
Foreach ($n in $cn.name)
{If(Test-WSMan -ComputerName $n -EA 0)
Finally, I use the Invoke-Command cmdlet to run my script on the remote machines. If the machine is not up (or not responding to Test-WsMan), I print the name of the remote computer that was not responding.
Note This command requires admin rights. I could supply alternate credentials if I needed to.
This could easily be modified to log to a file. Here is that command:
{Invoke-Command -ComputerName $n -FilePath $filepath}
ELSE {"$n is not available"} }
As shown here, I use Remote Desktop to connect to one of the remote servers to look at the Task Scheduler:
Here is the complete script:
$searchBase = "ou=servers,dc=nwtraders,dc=com"
$filepath = "C:\fso\CreateScheduledTaskFolderAndTask.ps1"
$cn = Get-ADComputer -Filter * -SearchBase $searchBase
Foreach ($n in $cn.name)
{If(Test-WSMan -ComputerName $n -EA 0)
{Invoke-Command -ComputerName $n -FilePath $filepath}
ELSE {"$n is not available"} }
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
0 comments