≡ Menu

After downloading a VHD from Microsoft site and trying to import in Hyper-V environment you may observe this error. This can happen in Windows Server 2012 or above.

Hyper-V-Failed-Add-Disk

Looking the error message, you may feel that this VHD doesn’t support the Hyper-V version I am running. But wait!!!. I have downloaded a Windows Server 2012 R2 evaluation VHD from Microsoft and it is not working on a Hyper-V which is running on Windows Server 2012. I don’t think Microsoft will do such silly things. After debugging for sometime, I recollected a article that wrote some days back. It is about sparse flag for the files downloaded from Microsoft website.

You can read the complete article at http://techibee.com/powershell/powershell-script-to-query-folder-size/1060

So, I quickly verified and noticed that the VHD I downloaded has this sparse file set. So, removing it should solve the problem.

I made use of the Remove-SparseFlag PowerShell function which I wrote in aforementioned article and  removed the flag. After that the VM started fine.

Remove-sparseflag

Hope this helps.

 

{ 0 comments }

PowerShell: Get Windows System Info in Object format

I came across a tip in twitter from Jeffry Snover that helps in converting the System Information from Windows System information into PowerShell object. This conversion helps in easily accessing the information just by accessing the Property values.

Look at below example for better understanding.

$Obj = systeminfo /FO CSV | ConvertFrom-CSV            
$Obj.'System Boot Time'            
$Obj.'System Type'            

The first line queries the System information from local computer and stores the value in $Obj after converting the output from CSV to Object format. Once the results are available in $Obj you can review the properties of this object and query the data you want. All you see in $Obj is same as what you see when systeminfo command is ran. It’s just that formatting the output and storing in object structure for better processing.

SystemInfo-Powershell

Here is the original tweet I am referring to.

Hope this tiny tip helps.

{ 0 comments }

Add Computers to WSUS Group Using PowerShell

WSUS is still a good choice for Windows Administrators to deploy patches. This article will demonstrate how to add a Computer account to WSUS Group using PowerShell.

This activity will look cumbersome and time consuming when you want to add large no. of computers to a WSUS Group. The manual procedure involves, searching each computer and right click on it, change group membership and then select the group name that you want to move.

I faced similar situation and wanted to automate it though it is a one time task for me. A quick search in Google led me to basics of managing WSUS using PowerShell written by Boe Prox. I make up a quick script based on this article and able to move computers to new group in no time.

First we need to establish connection to WSUS.

#Connect to WSUS server            
            
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")            
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer("localhost",$False)

Once the connection established, we should get a reference to Computer Group to which you want to add computers. The $GroupObj will hold the result.

#Get reference to WSUS Group to which you want to add computer account            
$GroupObj = $wsus.GetComputerTargetGroups() | ? {$_.Name -eq "MyNewGroup"}

Similarly we need to get reference to Computer object that we want to add. The SearchComputerTargets() method allows us to search for computer accounts matching a given name. Note that this method will always return a array even though the search returns a single computer object. That is the reason I have used a for loop to add all results from search operation. If you don’t want to perform add operations if the search results are more than one, then just perform a check on the $CompObj array to see how many items it is containing. If the count is 1, then search operation resulted in finding one computer. Based on this value you can process further.

#Search for the computer account that you want to add            
$CompObj = $wsus.SearchComputerTargets("Server01")            
            
#Add computer to the WSUS Group            
foreach($Comp in $COmpObj) {            
    $GroupObj.AddComputerTarget($Comp)            
}            

You won’t see a error message at the end of addition if successful.

Windows 8.1 and Windows Server 2012 R2 has a built PowerShell module for managing WSUS which you may want to take a look.

{ 0 comments }

Cheat Sheet for Process Management using PowerShell

Cheat Sheet for Process Management is a small handy guide for any process related operations using PowerShell. It covers most common and basic things related to windows processes that any Windows Admin want to perform on a day to day basis. If you are in the process of learning PowerShell, I prefer you keep a print of it at desk as a quick reference. These are simple one liners which are targeted perform more common tasks.

The current version of this cheat sheet covers following basic tasks. If you have any suggestion to include new items, please drop me a note(see about section in my blog).

  • Get all processes and list name, PID, exe path
  • Check if a process is running by Name
  • Check if a process is running(by PID)
  • Kill a process by name
  • Kill a process by pid
  • Query full path of a process executable
  • Get process id of a process
  • Get owner(user name) of a process
  • Get Creation time of a process
  • Start a new process(locally)
  • Start a new process(locally) and get pid of it
  • Start a new process(remotely)

Do you like this idea of preparing Cheat Sheet for frequently used PowerShell commands?? Provide your feed back in comments sections. That helps me to prepare future guides in the same line.

Files-Download-File-iconDOWNLOAD

{ 1 comment }

Remove empty items from array in PowerShell

Often we get this situation where in you read the contents of a file for servers list or some other content and end up with blank/empty items in the array because of empty lines in the files. This is often seen when doing split operation on array and because of string format you will end up with empty items in array.

The below example will give you understanding of what I am saying. Scenario#1 shows how blank entries will get added to array when you read the file contents using Get-Content cmdlets and Scenario#2 shows how you will end up with blank/empty entries when you split a string using Split() method. These are two most common cases where you will end up with empty items in resultant array.

array-emptylines

Now let us go ahead and see how to get rid of them.

Addressing scenario#1:

It can be addressed by using simple technique where you will check each item in array and verify if it is empty or not. Need even shorter solution? Try the below.

$content = Get-Content c:\temp\servers.txt            
Write-Host "Array size before removing empty lines : $($content.Count)"            
$content = $content | ? {$_}            
Write-Host "Array size AFTER removing empty lines : $($content.Count)"

remove-emptylines-1

I am not aware of any other better approaches, please feel free to share if you have better technique.

Addressing scenario#2:

Scenario#2 can also be addressed in same way as scenario#1 but I don’t want to do it since there is better approach. Let me be a good programmer.

$string = "try;splitting;;me;;by semi;;coluns;;to see what ;; happens;ok?"            
$string.Split(";",[System.StringSplitOptions]::RemoveEmptyEntries)

remove-emptylines-2

As you can see split() method can take a optional parameter called splitoptions where we can specify it to remove empty entries.

As you can see in output, empty lines are removed now.

{ 0 comments }

In my previous post, we explored the way to identify list of group policies linked to a particular Active Directory OU. While it serves the purpose, there are few details missing there like whether GPO is enabled, enforced, what is the order of the GPO, etc.

Articles related to working with Group Policies using PowerShell

  1. Find Group Policies Objects in Domain using PowerShell
  2. Find Group Policies linked to Active Directory OU Using PowerShell

The applicability of Group Policy object on an Active Directory OU completely replies on status of Group Policy link on that OU. If the status of Group Policy link is in enabled state, then policy will get applied. If the status is disabled, policy is not applicable for members inside that OU. Below screen shot shows the link enable status of a Group Policy on LAB OU from GPMC editor.

GPO-Link-Enabled

When the GPO link is disabled, it appears like below in GPMC editor.

GPO-Link-disabled

Similarly enforced option has its significance to decide policy applicability.

So let us see how we can identify the link status, enforcement status and order of a Group Policy object on a OU using PowerShell since this these plays vital role in deciding the GPO applicability to objects inside that OU>

In my previous post, I used a property called LinkedGroupPolicyObjects to retrieve list of linked Group Policies on OU. There is another property called gPLink which gives more details about the policy that is linked. The values inside gPlink property talks about list of policies, their order, link enable status, enforce status. The format of gplink property looks like below.

[<GPO DN_1>;<GPLinkOptions_1>][<GPO DN_2>;<GPLinkOptions_2>]… [<GPODN_n>;<GPLinkOptions_n>]

Where GPO DN is the distinguished name of the GPO and GPLinkOptions represent the GPO enabled and enforcement status. Also first DN in the string has high precedence order while the last one has low precedence order. You can find more details about this structure at http://msdn.microsoft.com/en-us/library/cc232505.aspx

The below script take a OU name, searches active directory for OUs having that name, queries the group policies linked to that OU, identifies link status, enforcement status, order details and returns the information in Object format.

Code:

[cmdletbinding()]            
param(            
 [string]$OUName            
)            
$OUs = @(Get-ADOrganizationalUnit -Filter * -Properties gPlink | ? {$_.Name -eq "$OUName"})            
#Return if no OUs found with given name            
if(!$OU) { Write-Warning "No such OU found"; return }            
            
foreach($OU in $OUs) {            
 $OUName = $OU.Name            
 $OUDN = $OU.DistinguishedName            
 #Hackey way to get LDAP strings. Regex might be best option here            
 $OUGPLinks = $OU.gPlink.split("][")            
 #Get rid of all empty entries the array            
 $OUGPLinks =  @($OUGPLinks | ? {$_})            
 $order = $OUGPLinks.count;            
 foreach($GpLink in $OUGPLinks) {            
   $GpName = [adsi]$GPlink.split(";")[0] | select -ExpandProperty displayName            
   $GpStatus = $GPlink.split(";")[1]            
   $EnableStatus = $EnforceStatus = 0            
   switch($GPStatus) {            
    "1" {$EnableStatus = $false; $EnforceStatus = $false}            
    "2" {$EnableStatus = $true; $EnforceStatus = $true}            
    "3" {$EnableStatus = $false; $EnforceStatus = $true}            
    "0" {$EnableStatus = $true; $EnforceStatus = $false}            
   }            
   $OutputObj = New-Object -TypeName PSobject            
   $OutputObj | Add-Member -MemberType NoteProperty -Name OUName -Value $OUName            
   $OutputObj | Add-Member -MemberType NoteProperty -Name OUDN -Value $OUDN            
   $OutputObj | Add-Member -MemberType NoteProperty -Name GPName -Value $GPName            
   $OutputObj | Add-Member -MemberType NoteProperty -Name IsLinked -Value $EnableStatus            
   $OutputObj | Add-Member -MemberType NoteProperty -Name IsEnforced -Value $EnforceStatus            
   $OutputObj | Add-Member -MemberType NoteProperty -Name GPOrder -Value $Order            
   $OutputObj            
   $order--            
 }            
            
}            
            
            
            

Output:

Group Policy link status

The output is easy to understand. It mentions about OU name, its DN, policy name, link status, enforcement status, and order of the GPO that you see in GPMC console.

gpo status in gpmc

Hope this helps.. stay tuned for more articles in future.

This script is also available at technet library (http://gallery.technet.microsoft.com/Get-GPO-link-status-a6e5fe7e)

{ 0 comments }

Last time we have seen a few ways to find group policies using PowerShell. Expanding on the same horizon, I would like to share some more thoughts on finding Group Policies linked to AD OUs.

If you haven’t read my previous article on finding group policies, I prefer you go through that first. Here is the link to it.

Find Group Policies Objects in Domain using PowerShell

The previous post is about basics of finding group policies, but how to we find what all policies linked to a particular organization Unit? This can be accomplished by using ActiveDirectory module and GroupPolicy module.

First let us import both the modules

Import-Module ActiveDirectory            
Import-Module GroupPolicy            

The Get-ADOrganizationalUnit cmdlets helps in querying the Active Directory Organization units. It returns AD Object of each OU. One of the property for OU object is LinkedGroupPolicyObjects which contains information about list of policies that are currently linked to the OU. See below example for better understanding.

Get-ADOrganizationalUnit -Filter 'Name -like "*lab*"'

PS C:\> Get-ADOrganizationalUnit -Filter ‘Name -like “*lab*”‘

City :
Country :
DistinguishedName : OU=LAB,DC=techibee,DC=ad
LinkedGroupPolicyObjects : {cn={98CBBC75-DE94-4093-9B46-D4100230849E},cn=policies,cn=system,DC=techibee,DC=ad}
ManagedBy :
Name : LAB
ObjectClass : organizationalUnit
ObjectGUID : dc39b7f3-fa61-400b-aa48-318b5ca959ca
PostalCode :
State :
StreetAddress :

In my case I have only one OU with the name lab so it returned single object. Based on the name of your OU, you may need to fine tune the filter part. As you can see in the output LinkedGroupPolicyObjects attribute is an array of linked Group policy object paths. So, we need to convert these distinguished names (DN) of the Group Policies into display names for better understanding.

There are two ways to do that.

Using Group Policy Module:

Using Group Policy cmdlets query the display name and other information of Group policy object like creation time, modified time, owner of GPO etc. I used a regex to take out the GUID of GPO from the DN and used it for searching the GPO using Get-GPO cmdlet.

$LinkedGPOs = Get-ADOrganizationalUnit -Filter 'Name -like "*lab*"' | select -ExpandProperty LinkedGroupPolicyObjects            
$GUIDRegex = "{[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}}"            
            
foreach($LinkedGPO in $LinkedGPOs) {            
    $result = [Regex]::Match($LinkedGPO,$GUIDRegex);            
    if($result.Success) {            
        $GPOGuid = $result.Value.TrimStart("{").TrimEnd("}")            
        Get-GPO -Guid $GPOGuid            
    }            
            
}

Using [ADSI]

The information about group policy can also be obtained using the [ADSI] interface. The information returned by this method is properties of Group policy object in active directory. This contains variety of information that you generally see in Active Directory for a GP object. Display Name, Sysvol path of GPO, etc. are available in the output.

$LinkedGPOs = Get-ADOrganizationalUnit -Filter 'Name -like "*lab*"' | select -ExpandProperty LinkedGroupPolicyObjects            
            
foreach($LinkedGPO in $LinkedGPOs) {             
[adsi]"LDAP://$LinkedGPO" | select DisplayName, WhenCreated, WhenChanged, gPCFileSysPath | fl             
            
}

Based on your comfort level you can choose one of these methods to query list of Group Policies linked to a OU.

Hope this helps and happy learning…

{ 3 comments }

Do you have a mix of Windows Server 2003 and Windows Server 2012 R2 domain controllers in your domain and occasionally experiencing logon issues? It could be due to Computers which changed their machine password recently and failing to communicate with domain after that. AskDS(Microsoft Active Directory support team) recently published an article about this which gives further details into this problem and a few possible workarounds. You might want to try them if you are seeing similar problems in your environment.

http://blogs.technet.com/b/askds/archive/2014/07/23/it-turns-out-that-weird-things-can-happen-when-you-mix-windows-server-2003-and-windows-server-2012-r2-domain-controllers.aspx

 

{ 0 comments }

I came across a post from a PowerShell MVP at happysysadmin.com blog about finding boot performance of Windows Client operating system with PowerShell. I liked this post alot because of very good explanation he provided about different parameters involved in boot and how to interpret them.

Worth taking a look.

http://www.happysysadm.com/2014/07/windows-boot-history-and-boot.html

Thanks  for this wonderful article.

{ 0 comments }

Find Group Policies Objects in Domain using PowerShell

Windows Server 2012 and Windows 8.1 has inbuilt module for managing Group Policy objects in Windows environment. It has a total of 26 cmdlets to serve different types of Group policy operations. In this article I will focus on Get-GPO cmdlet and its usage.

You can start with importing the module first.

Import-Module GroupPolicy

This module is made available automatically when you install domain controller role in Windows Server 2012. If you want to install this module on a member server running windows server 2012, you can do it by adding Group Policy Management feature. This installs both MMC and PowerShell modules.

gpo module install

If you want to install this feature also via PowerShell, then try the below two commands. This will install GPMC.

Import-Module ServerManager            
Add-WindowsFeature GPMC

Get total no. of cmdlets in GroupPolicy module

To see the no. of cmdlets available in this module, below command will help.

(Get-Command -Module GroupPolicy | ? {$_.CommandType -ne "Alias" }).Count

List all Group policies in domain.

If you want to list all Group policies in current domain, use Get-GPO cmdlet with -All parameter. This will all GPOs in the current domain. This will return information like Displayname, GUID, GPO status, creation and modified time, etc of each GPO.

Get-GPO -All

Search for a GPO

Searching for a GPO by display name is also easy. Its matter of filtering the output generated from Get-GPO cmdlets.

Get-Gpo -all | ? {$_.displayName -match "Logon" }

filter-gpo-by-name

Convert to GUID to Name and Name to GUID:

If you know GUID of a GPO, you can get the display name of and similarly you can get GUID if you know the display name of it. Finding this information in prior operation systems requires either nontrivial coding or usage of third party tools/scripts.

Get-GPO -Name LogonPolicy | select id
Get-GPO -Guid 98cbbc75-de94-4093-9b46-d4100230849e | select displayname

gpo-name-to-guid-to-name

Specify DC name/domain name to query:

If you would like to query Group policy information from a specific domain controller, you can do that by pointing Get-GPO cmdlet to domain controller by specifying -Server parameter. You can also specify the name of the domain in FQDN format.

Get-GPO -all -Server TIBDC1

Export Group policy information to CSV:

The group policy information can be easily exported to a CSV/Excel by using Export-CSV cmdlet in combination with Get-GPO cmdlet.

Get-GPO -all | export-csv c:\temp\GPOinfo.csv -NoTypeInformation

Hope this helps. Happy learning. In next post I will cover about other Group Policy cmdlets and their usage.

{ 2 comments }