The below script helps you to query scheduled tasks from remote computer which is running with Windows 7/Windows 2008 or above. You can use this script to query multiple computers to get all the scheduled tasks. You can also query the computer by using a scheduled task name as well.
<#
.Synopsis
Get the list of scheduled Tasks from Windows 7 or Windows 2008 computers
.Description
This script displays all the scheduled tasks available in a windows 7 or windows 2008 computer.
.Parameter ComputerName
Computer Name(s) from which you want to get the scheduled tasks information. If this
parameter is not used, the the script gets the scheduled tasks list from local computer.
.Parameter TaskName
Name of the scheduled task that you want to query. This is a optional parameter.
.Example 1
Get-ScheduledTask.ps1 -ComputerName Comp1, Comp2
Get the scheduled tasks information from listed computers.
.Example 2
Get-ScheduledTask.ps1 -ComputerName Comp1 -TaskName "Calibration Loader"
Get the details of given task from Comp1.
.Notes
NAME: Get-ScheduledTask.ps1
AUTHOR: Sitaram Pamarthi
WEBSITE: http://techibee.com
#>
[cmdletbinding()]
param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]] $ComputerName = $env:computername,
[string] $TaskName
)
#function to get all scheduled task folder details.
function Get-TaskSubFolders {
[cmdletbinding()]
param (
$FolderRef
)
$ArrFolders = @()
$folders = $folderRef.getfolders(1)
if($folders) {
foreach ($folder in $folders) {
$ArrFolders = $ArrFolders + $folder
if($folder.getfolders(1)) {
Get-TaskSubFolders -FolderRef $folder
}
}
}
return $ArrFolders
}
#MAIN
foreach ($Computer in $ComputerName) {
$SchService = New-Object -ComObject Schedule.Service
$SchService.Connect()
$Rootfolder = $SchService.GetFolder("\")
$folders = Get-Tasksubfolders -FolderRef $RootFolder
foreach($Folder in $folders) {
$Tasks = $folder.gettasks(1)
foreach($Task in $Tasks) {
$OutputObj = New-Object -TypeName PSobject
$OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer
$OutputObj | Add-Member -MemberType NoteProperty -Name TaskName -Value $Task.Name
$OutputObj | Add-Member -MemberType NoteProperty -Name TaskFolder -Value $Folder.path
$OutputObj | Add-Member -MemberType NoteProperty -Name IsEnabled -Value $task.enabled
$OutputObj | Add-Member -MemberType NoteProperty -Name LastRunTime -Value $task.LastRunTime
$OutputObj | Add-Member -MemberType NoteProperty -Name NextRunTime -Value $task.NextRunTime
if($TaskName) {
if($Task.Name -eq $TaskName) {
$OutputObj
}
} else {
$OutputObj
}
}
}
}
Output:
Feel Free to post here if you have any trouble in using this script. Happy to help!!!
While writing a script today, I faced a situation where I have a string like “This is my test string”. As you have already noticed there are more than one spaces at different places in the string. All I need to do is eliminate all spaces and fit the words alone into a array.
Since this is a split by white space operation, I tried below and got bit surprised with the output.
$string = "This is my test string"
$string.split(" ")
Output:

The output is array which is containing the words plus some spaces in middle. This is not what I expected. After some struggle, I made it to work by using -Split.
Now the working code is…
$string = "This is my test string"
$array = $string -split "\s+"
$array
Output:

Hope this little tip helps. Visit to http://www.powershelladmin.com/wiki/Powershell_split_operator for more examples about using -Split.
[Update]:
The usage for -split is very simple and I believe this is a best suit for simple requirements like the one I showed you above. But if you have something more complex, then you may want to explore the usage of [regedit]::Split() dotnet method.
One of my friend is trying to get computers list from active directory using below code. All he want is names of the computers in a array.
$TestPcNames = Get-QAComptuer -Id TEST* | select Name
$TestPCNames | % { write-host "$_.Name" }
There is nothing really wrong with the above code. All it contains is computer names but in object format. For that reason when he is trying to print the computer name, he is getting something like @{Name=TESTPC1}.Name
There he is stuck and now don’t know how to get list of computer accounts(in string format) in a array. This is very basic problem that every system administrator will face when trying to get their hands wet with powershell. I have also gone through this a couple of years back when I am studying ABCs of powershell.
The solution for this is very easy. First get the things printed correctly. You can use either of below one liners for that.
$TestPCNames | % { write-host "$($_.Name)" }
$TestPCNames | % { $_.Name }
Once you seen them printed as string array(you will noted there won’t be any column header with work “Name”), all you need to do is assign the output to a variable.
$CompArray = $TestPCNames | % { write-host "$($_.Name)" }
$CompArray = $TestPCNames | % { $_.Name }
Now $CompArray contains the list of computers. Hope this little tip helps…
Here is an interesting video about PowerShell V3 which I came across through linked in…
Thought of sharing with Scripting guys…
http://channel9.msdn.com/posts/PowerShell-V3-Guru-Don-Jones?goback=%2Egde_140856_member_112620896
“Could you please send me a screenshot of what you are seeing?”. This is a frequent question we system administrators ask the end users. So, I just got a thought why I can’t take a screenshot of desktop using powershell so that I can incorporate this to my other automations if needed. That is when this script born.
When searched in google for this, I found a stackoverflow thread(http://stackoverflow.com/questions/2969321/how-can-i-do-a-screen-capture-in-windows-powershell) where different approaches are described to take a screenshot using powershell. I could make only one method working and the other is having problems. However, the working method has a limitation as I need to explicitly pass the width and height of the screen that has to be captured. If I am interested on whole screen, from where I can get these coordinates? My previous post(Get-ScreenResolution) came handy here. I read the screen resolution details using Get-Screenresolution.ps1 script and passed the output to the function I found in stackoverflow. Now it is working exactly the way I want.
For general usage, I made few more modifications to the code to allow explicitly pass the width and height details using -Width and -Height parameters. There is also another parameter called -FileName using which you can provide the name you want for the screenshot. Don’t provide a file extension here. The script saves the output in PNG format by default. If -FileName parameter is not specified you can see the output in %temp% with Screenshot.png name.
Get-ScreenShot.ps1
[cmdletbinding()]
param(
[string]$Width,
[string]$Height,
[String]$FileName = "Screenshot"
)
#Function to take screenshot. This function takes the width and height of the screen that has
#to be captured
function Take-Screenshot{
[cmdletbinding()]
param(
[Drawing.Rectangle]$bounds,
[string]$path
)
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($path)
$graphics.Dispose()
$bmp.Dispose()
}
#Function to get the primary monitor resolution.
#This code is sourced from
# http://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615
function Get-ScreenResolution {
$Screens = [system.windows.forms.screen]::AllScreens
foreach ($Screen in $Screens) {
$DeviceName = $Screen.DeviceName
$Width = $Screen.Bounds.Width
$Height = $Screen.Bounds.Height
$IsPrimary = $Screen.Primary
$OutputObj = New-Object -TypeName PSobject
$OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName
$OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width
$OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height
$OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary
$OutputObj
}
}
#Main script begins
#By default captured screenshot will be saved in %temp% folder
#You can override it here if you want
$Filepath = join-path $env:temp $FileName
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")
if(!($width -and $height)) {
$screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}
$Width = $screen.Width
$Height = $screen.height
}
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)
Take-Screenshot -Bounds $bounds -Path "$Filepath.png"
#Now you have the screenshot
Usage:
Simple, just run the script from powershell window, you will see the output in %temp%\screenshot.png
Hope this helps… feedback welcome.
If you are using Write-EventLog to write any new events to event log, it is possible that you might see below error.
Write-EventLog : The source name “XXX” does not exist on computer “localhost”.
I am into similar situation today. What I was doing is trying to write a new event in to Application event log with a Event Source that is not already exists in the computer where I am trying. So the error message makes sense. It is saying the source I am trying to use, XXX doesn’t exists. So, how should get this added to list of available event sources in the computer so that it won’t through the error message again.
After little bit of googling, I found the below method promising.
New-EventLog -LogName Application -Source “XXX”
This command creates a new event source in Application Event log with the name XXX. All I need to do is just use this command once and try the write-EventLog cmdlet with the same source name(XXX). It worked this time.
Hope this little trick helps you…
[Update]
There are some dotnet ways available as well to see if a given source is available in EventLog and create one if needed.
To check if the source exists:
PS C:\> [system.diagnostics.eventlog]::SourceExists(“XXX”)
False
PS C:\>
To create a new source entry in event log:
[system.diagnostics.EventLog]::CreateEventSource(“XXX”, “Application”)
The Powershell code described in this article will help you to get screen resolution details of your desktops It uses System.Drawing and System.Windows.Forms namespaces. The Screen class in System.Windows.Forms provides the data we need — that is screen resolution details. This code will also tell you which one is your primary monitor and it’s resolution details.
Code:
function Get-ScreenResolution {
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Screens = [system.windows.forms.screen]::AllScreens
foreach ($Screen in $Screens) {
$DeviceName = $Screen.DeviceName
$Width = $Screen.Bounds.Width
$Height = $Screen.Bounds.Height
$IsPrimary = $Screen.Primary
$OutputObj = New-Object -TypeName PSobject
$OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName
$OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width
$OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height
$OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary
$OutputObj
}
}
Output:

Hope this helps…
In one of my previous posts I talked about how to disable/enable LAN connections on a Windows 2008 Core server using command line. In this post, I am going to present you a much enhanced version of it using powershell. This powershell script helps you to disable or enable any network connection in either local computer or remote computer easily. You can use this script to perform this operation on multiple computers — will give usage example at the end of this post.
In this script I am using Win32_NetworkAdapter WMI class which has methods for enabling or disabling a given network connection. By default, the script looks for network connections with the name Local Area Connection to perform disable or enable operations. If you want to perform these actions against different network connections(like HP Team#1) you can specify that using -ConnectionName parameter. The -Disable or -Enable parameters are for specifying the kind of operation you want to perform. The script will fail if you don’t find either of them. Similarly, you can use -ComputerName parameter if you want to perform this operation against remote computer. You can also provide the list of computers to this argument. I want you be more conscious while using this script against remote computer. The reason behind it is, if you are attempting to disable the primary network connection in remote computer, the script may not return the success/failure status. The reason is simple, it lost the connection to remote computer because you just disabled it. You may find this script handy when you want to disable non-primary connections on remote computers. Since the primary connection is ON in this case, this can return you the status. I didn’t perform any testing against remote computers explicitly so please do testing in your test lab before trying in production.
Code : Set-NetworkConnection.ps1
[cmdletbinding()]
param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:computername,
[switch]$Enable,
[switch]$Disable,
[String]$ConnectionName = "Local Area Connection"
)
begin {
if(-not($enable -or $disable)) {
write-Error " You should select either of -Enable or -Disable switches. Exiting"
exit
}
}
process {
foreach ($Computer in $ComputerName) {
$Computer = $Computer.ToUpper()
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Networks = Get-WmiObject Win32_NetworkAdapter -ComputerName $Computer | ? {$_.NetConnectionID -match $ConnectionName}
foreach ($Network in $Networks) {
if($Enable) {
$retval = $Network.Enable()
if($retval.ReturnValue -eq 0) {
Write-host "Successfully enabled `"$($network.NetConnectionID)`" on $Computer"
} else {
write-host "Failed to enable `"$($network.NetConnectionID)`" on $Computer"
}
} elseif($Disable) {
$retval = $Network.Disable()
if($retval.returnValue -eq 0) {
Write-host "Successfully disabled `"$($network.NetConnectionID)`" on $Computer"
} else {
write-host "Failed to disable `"$($network.NetConnectionID)`" on $Computer"
}
}
}
}
}
}
end {}
Usage Examples:
.\Set-NetworkConnection -Enable #to enable local network connection
.\Set-NetworkConnection -Disable #to disable local network connection
.\Set-NetworkConnection -Disable -ConnectionName “My network2″ #to disable the local network connection that has the name “My Network2″
.\Set-NetworkConnection -ComputerName MyPC2 -Disable -ConnectionName “My network2″ #to disable the network connection that has the name “My Network2″ on MyPC2
Get-Content C:\mypcs.txt | Set-NetworkConnection -Disable -ConnectionName “My Network2″ #To disable the network connection name “My network2″ on list of PCs in C:\mypcs.txt file
Hope this helps… Happy learning…
Would it not be helpful if all scripts are at one place and you can navigate/browse them through single window?
Microsoft team is working on a tool called Script Explorer for Windows Powershell.
Go through below link for more details.
http://blogs.technet.com/b/exchange/archive/2012/03/14/check-out-microsoft-script-explorer-for-windows-powershell-pre-release.aspx
As promised in my previous post,I am back with a Powershell script which helps you in deleting a user’s windows profile either on local computer or on multiple remote computers. This script users Win32_UserProfile class which is available in Windows Vista, Windows 7, and Windows 2008(R2). So it will not work for Windows XP and 2003 hosts.
In this script I am making use of a method called Delete() which is available for each profile queried through Win32_UserProfile WMI class. Using this script you can delete one profile at a time on a single computer or list of remote computers. This script will also display the result of operation you are performing. That means it will tell whether it succeed in deleting the profile or failed. And it will also tell you if the script is unable to find the profile you are trying to delete.
Code: Remove-UserProfile.ps1
[cmdletbinding()]
param(
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:computername,
[parameter(mandatory=$true)]
[string]$UserName
)
foreach($Computer in $ComputerName) {
Write-Verbose "Working on $Computer"
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Profiles = Get-WmiObject -Class Win32_UserProfile -Computer $Computer -ea 0
foreach ($profile in $profiles) {
$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.sid)
$objuser = $objsid.Translate([System.Security.Principal.NTAccount])
$profilename = $objuser.value.split("\")[1]
if($profilename -eq $UserName) {
$profilefound = $true
try {
$profile.delete()
Write-Host "$UserName profile deleted successfully on $Computer"
} catch {
Write-Host "Failed to delete the profile, $UserName on $Computer"
}
}
}
if(!$profilefound) {
write-Warning "No profiles found on $Computer with Name $UserName"
}
} else {
write-verbose "$Computer Not reachable"
}
}
Output:

You can use this script to delete profile from list of remote computers either by providing the list via command line or using a text file. See below two cases to get more insight about how to use the script in such cases.
.\Remove-UserProfile.ps1 -ComputerName PC1, PC2, PC3 -UserName LocalUser2
Get-Content c:\temp\Computers.txt | .\Remove-UserProfile.ps1 -UserName LocalUser2
Hope this helps… Feel free to write in comments section if you have any doubts or looking for some enhancements to the script. Happy to help.