Archive

Archive for the ‘PowerShell’ Category

Powershell: Script to enable/disable network connections in Windows

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…

Microsoft Script Explorer for Windows PowerShell (pre-release)

April 11, 2012 1 comment

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

Powershell: Script to delete Windows User Profiles on Windows 7/Windows 2008 R2

March 24, 2012 7 comments

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.

 

Powershell: Script Get Windows User Profiles on Remote Computer

March 21, 2012 1 comment

I recently came across a requirement to list the User profiles in remote computer. I can do a quick dir of \\pc1\c$\users to get the list of profiles but that is not efficient. It is quite possible that profiles are placed in different drive/directory. After some research, I stumbled on a WMI class WIn32_UserProfile using which I can get the profiles list I wanted. I read about this class and what it can offer. Interestingly, I can get more details about a profile with this class. I can check if a profile is local, roaming, temporary, random or a corrupted one. This data is useful various scenarios. Also I can check if a profile is a human profile or it belongs to system (that means system is maintaining it — ex: networkservice).

So, the script discussed in this article will help you to get list of user profiles on remote computer and what type of profile it is, profile path (where the profile is stored), and will tell you if the profile is non-system profile or system profile.

One thing I must note here is, Win32_UserProfile WMI class is available in systems greater than Windows Vista/Windows 2008. The previous Operating Systems are not having this class. It means that script will not work for any computers having prior operating systems like Windows 2003/2000/XP, etc.

Script : Get-UserProfile.ps1

[cmdletbinding()]
param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:computername,
[string]$UserName
)            

foreach ($Computer in $ComputerName) {
 $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])
  switch($status) {
   1 { $profileType="Temporary" }
   2 { $profileType="Roaming" }
   4 { $profileType="Mandatory" }
   8 { $profileType="Corrupted" }
   default { $profileType = "LOCAL" }
  }
  $User = $objUser.Value
  $ProfileLastUseTime = ([WMI]"").Converttodatetime($profile.lastusetime)
  $OutputObj = New-Object -TypeName PSobject
  $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.toUpper()
  $OutputObj | Add-Member -MemberType NoteProperty -Name ProfileName -Value $objuser.value
  $OutputObj | Add-Member -MemberType NoteProperty -Name ProfilePath -Value $profile.localpath
  $OutputObj | Add-Member -MemberType NoteProperty -Name ProfileType -Value $ProfileType
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsinUse -Value $profile.loaded
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsSystemAccount -Value $profile.special
  if($UserName) {
   if($User -match $UserName) {
    $OutputObj
   }
  } else {
   $OutputObj
  }
 }
}

Output:

 

By default the script gets you all profiles in the computer. If you are looking for the details of a specific profile, just use the -UserName Parameter. For example, to get the profile of LocalUser1, use .\Get-UserProfiles.ps1 -UserName localuser1

Similarly to get the profiles on remote computer, use -ComputerName parameter. See below image for examples.

In my next post I will write about how to delete windows user profiles using powershell script and Win32_UserProfile WMI class.

Powershell: Collection of FREE e-books for download

March 15, 2012 2 comments

The purpose of this post is to share free resources that are available in internet to learn Powershell. I feel this information is very useful to newbies’ who are willing to learn this power scripting language.

The books listed here are neither in the order I recommend reading them nor based on the worthy content they have. It is just a random listing and each one is having its own significance and importance. The list I am including here is completely free and you can download them(may be some needs registration). Also this is not the final list, I will keep adding the content when even I find it. Please subscribe yourself to either my twitter updates(@pamarths) or subscribe to RSS to stay tuned.

If you come across any other free powershell resources that are worth sharing with everyone in PS planet, please either provide the link in comments section or just email me.

Book#1: Windows Powershell Workbook : Server administration

Content: Introduction to Powershell and performing Administrative tasks with it.

Download Link: http://download.microsoft.com/download/4/7/1/47104ec6-410d-4492-890b-2a34900c9df2/Workshops-EN.zip

Source : http://blogs.technet.com/b/chitpro-de/archive/2008/02/28/free-windows-powershell-workbook-server-administration.aspx

Book#2: The Administrator Crash Course: Windows PowerShell v2

Content: It contains crash course material for learning Powershell in 4 weeks.

Download Link: http://nexus.realtimepublishers.com/accwp.php

Book#3:  Effective Windows Powershell

Download Link: http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/

 Book#4: Layman’s Guide to Powershell 2.0 Remoting

Download Link: http://www.ravichaganti.com/blog/?page_id=1301

Book#5: WMI Query Language(WQL) Via Powershell

Download Link: http://www.ravichaganti.com/blog/?page_id=2134

Book#6: Mastering Powershell

Download Link: http://powershell.com/cs/blogs/ebook/

This is one of my favorite online resources for learning powershell.

 Book#7: Administrator’s Guide to Windows PowerShell Remoting

Download Link: http://powershell.com/cs/media/p/4908.aspx

More coming up….

Powershell: Create new mailbox database

After installing MS Exchange 2010 in my test lab, I want to create new mailbox database in my server. While I can do it with GUI, I am more interested in exploring the powershell way…

The exchange management shell is having very large set of cmdlets to manage exchange. In fact the GUI also is a wrapper on top of Powershell commands. So learning these commands and using them in daily operations is really useful and you can go into granular details.

New-MailboxDatabase is the cmdlet that accomplished my task here.

New-MailboxDatabase -EdbFilePath C:\Database\MailboxDB1.edb -Server TIBDC1 -Name MailDB1

Here I am creating a new mailbox database with name MailboxDB1 and placing the EDB file C:\Database folder with MailboxDB1.EDB file name. You might ask what happens to log files and where they will be saved. By default logfiles go with EDB file unless the path is specified with -LogFolderPath parameter. The -Server parameter specifies the server name where this database is going to be created.

You won’t see the creation of EDB file or logfiles in the given folder unless you mount it. So we need to use Mount-Database cmdlet to mount the newly created database. You can use the below command for that purpose.

Get-MailboxDatabase -Identity MailDB1 | Mount-Database

Hope this helps… and you will see more exchange stuff in my upcoming posts.

 

Powershell: How to get Groups list of a computer account

One of my old friend/colleague called me to day for a small help. He is looking for script to get the list of active directory groups that a computer account is member of. Since this is a very basic requirement every System administrator will get, I wanted to post it in my blog.

So, the code described in this post uses Quest Active Directory powershell cmdlets. I can code using the dotnet objects or built-in activedirectory module in windows 7/2008 as well but since I wanted to make it more generic, I opted for Quest cmdlets. Another advantage is that even newbies can query AD with these tools efficiently.

Since I am using Quest AD cmdlets, you should down load them from http://www.quest.com/powershell/activeroles-server.aspx and installed it on your computer. After installation, copy the below code into a file called Get-ComputerGroups.ps1 and run it from Quest AD shell(you can launch this from program files), as shown below.

Get-ComputerGroups.ps1

[cmdletbinding()]
param(
[parameter(mandatory=$true)]
$ComputerName
)            

$Groups = (Get-QADComputer -Id $ComputerName).Memberof            

$Groups | % {
$_.split(",")[0].Split("=")[1]
}

Usage:

[PS] C:\temp\Get-ComputerGroups.p1 -ComputerName MyPC1

Here -ComputerName parameter is mandatory.

Similarly, if you want to provide the computer names from text file and get the active directory group names of all of them, then use the below code.

Get-ComputerGroups.ps1

[cmdletbinding()]
param(
[parameter(mandatory=$true)]
$FilePath
)            

$Computers = Get-Content $FilePath
foreach ($ComputerName in $Computers) {
    write-host "$ComputerName is memberOf following Groups"
    $Groups = (Get-QADComputer -Id $ComputerName).Memberof
    $Groups | % {
    $_.split(",")[0].Split("=")[1]
}            

}

Usage:

[PS] C:\> Get-ComputerGroups.ps1 -FilePath c:\temp\Computersfile.txt

If you want to redirect the output to a text file, just try the below command.

[PS] C:\> Get-ComputerGroups.ps1 -FilePath c:\temp\Computersfile.txt | Out-File c:\temp\output.txt

The output will be written to output.txt file.

Feel free to comment here if you have any doubts.

 

Powershell: Change/Set Power plans in Windows 7/Windows 2008 R2

February 28, 2012 1 comment

Are you looking for a way to change power plan on local or remote computer? You are at the right place. The script discussed in this article will help you in changing the power plans in PowerShell way. MS built-in tool(powercfg.exe) is available that can also help you to do this job. But I am not using that tool in my script by building a wrapper around it. I am simply relying on WMI class to change the power plan. I recommend WMI way because using executables inside script is not a good practice and it should be our last resort when it is not possible through WMI or dotnet class or some API.

The Win32_Powerplan WMI class will return list of power plans available in the computer. This list includes built-in power plans like”Power Saver”, “Balanced” and “high performance” plus any custom power plans that user has created. Each returned power plan a again  a object which will have a method called Activate() to activate the current power plan. This power plan object also contains a proper called IsActive which will be set to $true if is the active power plan that system is using currently.

The code follows…

Set-PowerPlan.ps1

[cmdletbinding()]                        

param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:computername,                        

[ValidateNotNullOrEmpty()]
[parameter(Mandatory=$true)]
[ValidateSet("Power Saver", "Balanced", "High Performance")]
[string]$PowerPlan                        

)                        

begin{}                        

Process {
foreach ($Computer in $ComputerName) {
 if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
  Write-Verbose "$Computer is online"
  $PreviousPowerPlan = Get-WmiObject -Class Win32_Powerplan -Namespace root\CIMV2\Power -ComputerName $Computer | ? {$_.IsActive -eq $true}
  $CurrentPowerPlan  = Get-WmiObject -Class Win32_Powerplan -Namespace root\CIMV2\Power -ComputerName $Computer | ? {$_.ElementName -eq $PowerPlan}
  $CurrentPowerPlan.Activate()
  $OutputObj  = New-Object -Type PSObject
  $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
  $OutputObj | Add-Member -MemberType NoteProperty -Name PreviousPlan -Value $PreviousPowerPlan.ElementName
  $OutputObj | Add-Member -MemberType NoteProperty -Name CurrentPlan -Value $CurrentPowerPlan.ElementName
  $OutputObj
 } else {
  write-Verbose "$Computer is offline"
 }
}            

}                        

end {}

 

Save the above code into a file called “Set-PowerPlan.ps1″ and it is ready for usage. You can use -ComputerName parameter if you want to run against a computer. If this parameter is not specified, it runs on local computer.

Go through the below examples for usage instructions and let me know if you have any questions.

Hope this helps…

Powershell: Get Active Directory Sites and subnets list

February 25, 2012 1 comment

This post talks about querying Active Directory Sites and subnets information from AD using Powershell. This script is helpful when you want to know subnets mapping to given site and servers lying in a site. This scrip doesn’t need much explanation since it is looking very straight forward. If you defer with me, please comment what part of script you want to understand. Also feel free to post if you would like to query any other information related to sites and services. Happy to help.

Code: Get-ADSites.ps1

[cmdletbinding()]
param()            

$Sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites            

foreach ($Site in $Sites) {            

 $obj = New-Object -Type PSObject -Property (
  @{
   "SiteName"  = $site.Name;
   "SubNets" = $site.Subnets;
   "Servers" = $Site.Servers
  }
 )            

 $Obj
}

 Output

Powershell: Uninstall software on remote computer

February 20, 2012 2 comments

Ok. It’s time to uninstall a application using powershell. This post is continuation to Powershell: Script to query softwares installed on remote computer where I discussed about procedure to query installed applications on remote computer without using Win32_Product WMI class. The one advantage with Win32_Product WMI class is it’s uninstall() function using which we can trigger uninstallation of softwares on local or remote computer.

In this post, I am going to provide a powershell script which provides same functionality as uninstall() function of Win32_Product WMI class. My code uses GUID of product to trigger the uninstallation by passing it to msiexec process. It also triggers the uninstallation in silent mode so no UI will appear for the user while performing the uninstallation.

Code goes here…

[cmdletbinding()]            

param (            

 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
 [string]$ComputerName = $env:computername,
 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
 [string]$AppGUID
)            

 try {
  $returnval = ([WMICLASS]"\\$computerName\ROOT\CIMV2:win32_process").Create("msiexec `/x$AppGUID `/qn")
 } catch {
  write-error "Failed to trigger the uninstallation. Review the error message"
  $_
  exit
 }
 switch ($($returnval.returnvalue)){
  0 { "Uninstallation command triggered successfully" }
  2 { "You don't have sufficient permissions to trigger the command on $Computer" }
  3 { "You don't have sufficient permissions to trigger the command on $Computer" }
  8 { "An unknown error has occurred" }
  9 { "Path Not Found" }
  9 { "Invalid Parameter"}
 }

Note that you need my previous script(Get-InstalledSoftware.ps1) and the one discussed in this article(Uninstall-InstalledSoftware.ps1) to make this uninstallation works since the code discussed in this article depends on the output of Get-InstalledSoftware.ps1 script.

Usage:

  1. Run Get-InstalledSoftware.ps1 script and note the GUID of application that you want to uninstall.
  2. Run Uninstall-InstalledSoftware.ps1 -GUID <<uninstall application GUID here>>

Uninstall-InstalledSoftware.ps1 -GUID “{54D3F6B5-515B-45B8-8F41-FC4D26FEFFEA}”

Test this script in test environment before you try on any production computer. Any improper use of this script can trigger the uninstallation of multiple applications if handled improperly.

This can made as single liner…..

.\Get-InstalledSoftware.ps1 -ComputerName MyPC1 | ? {$_.AppName -eq “iTunes” } | .\Uninstall-InstalledSoftware.ps1

This triggers the installation of iTunes applications. Please note that at any point of time you are passing the output single computer to Uninstall-InstalledSoftware.ps1.

This is just a initial version. I will enhance it to accept multiple computers and multiple uninstallations at same time. I will also make it more robust to track the uninstallation process.

Hope this helps..

Your comments are welcome