≡ Menu

In this post I will show you how to query active directory security group members and export them to CSV(or excel) using PowerShell

While there are variety of ways available to export group membership to excel/CSV, the easiest method I found is using the combination of cmdlets in ActiveDirectory module & Export-CSV cmdlets. It helps you in exporting the member’s information to CSV file and it’s not much efforts to convert that CSV into EXCEL format if you insist that you need in XLS format only.

Since this code I am going to discuss uses ActiveDirectory module, make sure that you have at least one Domain Controller running ADWS service. Without that ActiveDirectory module will not work. ADWS is default with Domain Controllers running Windows Server 2008 R2 or above. For the lower versions, you need to install it manually. You can download ADWS for Windows Server 2003 and Windows Server 2008 from http://www.microsoft.com/en-sg/download/details.aspx?id=2852

Ok, now let jump the coding section.

First of all you need to import the ActiveDirectory module. This module is available on Windows 7 and Windows server 2008 or above only. If you have lower versions of operating systems, this is not available.

Import-Module ActiveDirectory

Once the module is imported, we can query the group members using Get-ADGroupMember cmdlet in this module

For example,

Get-ADGroupMember -Id "Group Name"

This will return list of objects that are part of the group. The objects include Users, computers and Group objects if any.

If you want to export this entire information to CSV, use Export-CSV cmdlet.

Get-ADGroupMember -Id "Group Name" | Export-CSV c:\temp\GroupOutput.CSV -NoTypeInformation

The above command is self-explanatory. I have used -NotypeInformation parameter for Export-CSV cmdlet to supress the type information of the objects it is exporting.

If you want to export group membership of multiple groups, then you have to try the below code.

Here the script reads the groups list from text file c:\temp\groups.txt and generates the output in c:\temp\GroupsInfo.CSV. The output will have the group name in first column.

$groups = Get-Content c:\temp\Groups.txt            
            
foreach($Group in $Groups) {            
            
Get-ADGroupMember -Id $Group | select  @{Expression={$Group};Label="Group Name"},* | Export-CSV c:\temp\GroupsInfo.CSV -NoTypeInformation -Append
            
}

Hope this helps and happy learning.

{ 16 comments }

Whenever a mailbox is moved in Exchange environment, it creates a move mailbox request entry to track the movement progress. This request will be set to completed once the movement is completed. However, this entry will not be deleted unless the Exchange admin deletes manually. If not done, when the same mailbox move is attempted, it will fail saying another request is in queue. So it is good to delete the completed/failed requests.There is no harm in removing these completed/failed requests.

To view the list of move requests in completed state, try the below command from exchange shell.

Get-MoveRequest | ? {$_.Status -eq "Completed" }

If you want to view the pending requests of a particular account, try the below. Here I am querying for testuser2 mailbox.

Get-MoveRequest -Identity testuser2

Use the below command to clear all completed move requests at single go.

Get-MoveRequest | Remove-MoveRequest -Confirm:$false

Use below command to clear move requests of a given mailbox

Get-MoveRequest -Identity test2 | Remove-MoveRequest -Confirm:$false

All these commands should be executed from Exchange Management Shell

{ 0 comments }

Querying Hyper-V made simple with Windows 8.1 and Windows Server 2012. But these two are latest version of Operating Systems and most of the people haven’t tried them yet in corporate environment. In this post I will demonstrate how to use WMI and Powershell to query a Hyper-V server without the use of MS given Powershell module or any other third party module.

When Hyper-V role is installed on a Windows server, it creates a set of WMI classes which we can query to get the required information.

To see list of WMI classes available, just run the below command on a Server where hyper-V role is available. All the Hyper-V related WMI classes are under “root\Virtualization” name space. You can query these classes remotely also like any other WMI class.

Get-WmiObject -Namespace root\virtualization -List

The WMI classes count might vary from Windows 2008 to Windows 2012 because of added features set. In this demonstration let us see how to get list of virtual machine names from Hyper-V using these WMI classes.

Details of virtual machines are stored under Msvm_ComputerSystem WMI class so querying this should list the names of the VMs hosted on the Hyper-V server.

Get-WmiObject -Class Msvm_ComputerSystem -Namespace "root\virtualization" | ? {$_.Caption -eq "Virtual Machine" } | select ElementName

If you notice the above command, I have used additional filtering by caption because by default this WMI class returns the name of the Hyper-V host as well – so to remove it from the list, I used filter to list down only virtual machines.

Hope this helps and happy learning.

{ 6 comments }

I am using Windows 8 for quite some time. Since I have UAC enabled in my computer, I need elevated command prompt to perform some actions. There are many articles on internet explaining different procedures to open an elevated command prompt. Most of them are using the search option in Windows 8. These approaches are taking more than 2-3 clicks to open a command prompt and being a system administrator I hate to follow such no. of steps to open my frequently used app. After some search over internet, I found my answer. It is as simple as pressing “Windows logo key Windows logo key +X” and then “A”. When you press Windows logo key Windows logo key +X, it will open Quick menu like shown in below screen and now pressing A will open command prompt in elevated mode. There are quite useful other shortcuts also available here.

Do you want to see how quick I can open now?

{ 0 comments }

By default, only administrators can view security event log in a Windows Server 2003 or 2008. In this article I will show you how to grant permissions to other users or groups to view security log content in a server without admin permissions.

For Windows Server 2008:

Let me start with something easy. For windows 2008 servers, it is very straight forward. If you want to allow any user or group view security event log, just add them to “BUILT IN\Event Log Readers” group and the task is accomplished. If you want to view who all has access to a given event log, try the below command

wevtutil gl security

For Windows Server 2003:

Like Windows server 2008, there is no straightforward way in Windows Server 2003. We need to tweak registry entries a bit to get the desired results. In Windows 2003, security log permissions are stored in registry key in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\Security\CustomSD registry value. The data for this value will be in SDDL format (search for SDDL in MSDN to know more). We need to modify the data of this value to grant permissions to new users or groups.

Now I will show two cases of granting permissions to security event log and you can form your own SDDL based on these examples.

Grant security log access to anyone logging into the computer:

Anyone who is logging into the computer either through RDP or via console is treated as a “Interactive User”. So granting permission to interactive user will give them required access to security event log. In this example, I am giving read-only access to all the users who is logging in interactive to the server. For that I just need to append the below SDDL string to aforementioned CustomID registry value. Make sure to append it without quotes.

“(A;;0x1;;;IU)” – append this without quotes

If you want to give them full access, then use the below SDDL.

“(A;;0xf0007;;;IU)”

Grant security log access to a user or group:

For granting security log access to a user or group, you need to have their SID handy so that you can form the SDDL to grant them access. You can refer to https://techibee.com/sysadmins/fetch-the-sid-of-a-user-account-using-powershell/137 if you want to know how to get SID of a user using powershell. Once you have the SID handy, you can form the SDDL string to append to the CustomID registry value. In this example, I am using the SID of my domain user “S-1-5-21-1377399363-320120969-1166362429-510”. To grant this user read-only access, I need to append below SDDL string to the CustomID registry value.

“(A;;0x1;;;S-1-5-21-1377399363-320120969-1166362429-510)”

Similarly you can grant permissions to security group as well by replacing the group SID in the above example.

This completes the procedure for granting permissions to read security log entries for non-admin users.

A few useful links:

Default ACLs on Windows event logs  — http://blogs.msdn.com/b/ericfitz/archive/2006/03/01/541462.aspx

How to set security event log security locally or using group policies –

http://support.microsoft.com/default.aspx?scid=kb;en-us;323076

Some more deep dive into permissions —  http://blogs.technet.com/b/janelewis/archive/2010/04/30/giving-non-administrators-permission-to-read-event-logs-windows-2003-and-windows-2008.aspx

Well known security identifiers in Windows –

https://support.microsoft.com/kb/243330

Hope this helps.. Happy learning.

{ 1 comment }

New year wishes to my blog readers

A very happy and prosperous New Year to all my blog readers. I hope my articles in the blog are useful and you enjoy reading the content. I am really enjoying blogging and learning a lot from this.

I will do my best to keep the quality content flow in this blog. If you have any suggestions about type of content or any other, please feel free to send me an email; we can discuss further. Two frequent topics that people often ask me about are free e-books for learning and interview questions for Windows administrators. I have already written a few articles about free e-books (search the blog) and will try to keep them up to date. Interview questions is not something I focused so far but it is in my to-do list.  I try to blog some content about this soon.

Once again Happy New Year and happy learning.

{ 0 comments }

The PowerShell function discussed in this article will help you to find out list of Hyper-V servers in Domain.

In today’s post, let us see how to find list of Hyper-V servers in domain. Whenever a Hyper-V server is added to active directory, it creates a Service Connection point (SCP) object in Active Directory under the Hyper-V server computer name with name “Microsoft Hyper-V”. This SCP can be used to discover list of Hyper-V servers in active directory. Both Hyper-V2008 and 2012 exhibit this behavior. Now let us form a script based on this information to get Hyper-V servers in Active Directory.

Code:

function Get-HyperVServersInDomain {            
[cmdletbinding()]            
param(            
)            
try {            
 Import-Module ActiveDirectory -ErrorAction Stop            
} catch {            
 Write-Warning "Failed to import Active Directory module. Exiting"            
 return            
}            

try {            
 $Hypervs = Get-ADObject -Filter 'ObjectClass -eq "serviceConnectionPoint" -and Name -eq "Microsoft Hyper-V"' -ErrorAction Stop            
} catch {            
 Write-Error "Failed to query active directory. More details : $_"            
}            
foreach($Hyperv in $Hypervs) {            
 $temp = $Hyperv.DistinguishedName.split(",")            
 $HypervDN = $temp[1..$temp.Count] -join ","            
 $Comp = Get-ADComputer -Id $HypervDN -Prop *            
 $OutputObj = New-Object PSObject -Prop (            
 @{            
  HyperVName = $Comp.Name            
  OSVersion = $($comp.operatingSystem)            
 })            
 $OutputObj            
}            
}

In this script I am using a flaky code to get computer DN from SCP DN. I couldn’t find any better way at the moment. Please share if you are aware of any.

Output:

HyerVInDomain

Hope this helps.

{ 4 comments }

The Powershell script discussed in this article will help you to find out the physical host name of a virtual machine using powershell. It works for both VMware based virtual machines and Hyper-V based virtual machines.

Virtualization is growing very fast and many companies switching most of their infrastructure to virtual space. Depending on budget and feature set requirements companies are switching to VMware or Hyper-V virtualization. In some cases, they place critical servers in VMware and low priority in Hyper-V. Since the virtual world is spread across multiple platforms, there is a need to identify the physical host of a given virtual machine. Though companies maintain some sort of naming convention, it is not a full-fledged solution to determine if a host is physical or virtual. This is even truer in cases where P2V is performed to migrate physical machines to virtual world where name of the computer is not changed. I too had such requirement and thought that building a script for this is very useful for everyone.

Each virtual machine stores the physical host information in registry at “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters” in PhysicalHostName value. So to get physical host name of a virtual machine, we should just query the data of aforementioned registry value. The below script helps you in that course. Before querying the registry, first it verifies if the given host is virtual or not by verifying its mode. This is done by querying model attribute of Win32_ComputerSystem WMI class. If it is a virtual machine, then the script makes a remote registry call using [Microsoft.Win32.RegistryKey] dotnet class and connects to HKLM and then queries the value of the key mentioned before.

The script is capable of taking multiple computers from command line find their physical host names.

Save the below code into a file (Get-PhysicalHostName.ps1 for example) and use as shown below.

.\get-physicalhostname.ps1 –computername computer1,computer2

[This code is working for only Hyper-V servers at the moment. I am working on how to device this information for VMware VMs as well]

[cmdletbinding()]            
param(            
 [string[]]$ComputerName = $env:ComputerName            
)            
$KeyName = "SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters"            
$ValueName = "PhysicalHostName"            

foreach($Computer in $ComputerName) {            
 if(!(Test-Connection -ComputerName $Computer -Count 1 -quiet)) {             
  Write-Warning "$Computer is offline"            
  Continue             
 }            

 try {            
  $CompObj = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $Computer -ErrorAction Stop            
  if($CompObj.Model -notmatch "Virtual") { throw "Not a virtual machine" }            

 } catch {            
  Write-Warning "$Computer : FAILED. Details : $_"            
  Continue            
 }            

 try {            
  $BaseKeyObj = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $computer)            
  $KeyObj = $BaseKeyObj.OpenSubKey($KeyName)            
  $Hostname = $KeyObj.GetValue($ValueName)            
 } catch {            
  Write-Warning "$Computer : Failed to get Physical host name. Details : $_"            
  Continue            
 }            

 $OutputObj = New-Object PSObject -Prop (            
  @{            
   ComputerName = $Computer.ToUpper()            
   PhysicalHostName = $Hostname            
  })            
 $OutputObj            

}

Hope this helps…

{ 8 comments }

The powershell script discussed in this article will help you reset and purge the policies on a SCCM client remotely using PowerShell.

SCCM(System Centre Configuration Manager) has variety of WMI classes and one of them is SMS_Client. This class helps you querying the machine policy remotely as well as reset and purge the existing policies.

You can check http://msdn.microsoft.com/en-us/library/cc146352.aspx for various methods available in this class. The script I am going to discuss below relies on ResetPolicy method to reset and purge the policies.

The script takes two arguments. 1) ComputerName 2) Purge. You can pass one or more computers(cama separated) to the ComputerName parameter. When this parameter is not specified it executes against local computer. The Purge argument is a switch type parameter. When it is used, the policy data will be purged. When not specified the reset policy will get executed with argument 1 which means full download of existing policy.

[cmdletbinding()]            
param(            
[string[]]$ComputerName = $env:ComputerName,            
[switch]$Purge = 0            
)            

if($Purge) {            
 $Gflag = 1            
} else {            
 $Gflag = 0            
}            

foreach($Computer in $ComputerName) {            
 $client = Get-WMIObject -Class SMS_Client -Namespace root\ccm -ComputerName $Computer            
 $returnval = $Client.ResetPolicy($Gflag)            
 if($returnvalue) {            
 Write-Warning "Error occurred while resetting/purging the policy on $Computer"            
 } else {            
 Write-Host "Purge/Reset successful on $Computer"            
 }            
}

I learned this from one of the contributor in “Hyderabad Powershell User Group” FB group. I am not an expert in SCCM but given that use case of this seems very high, I thought of converting it to a post.

Since I haven’t tried this script practically, I STRONGLY request you to try in a lab environment to see if it is giving desired results. Use at your own risk.

{ 6 comments }

In this article, I will show you how to create multiple test user accounts in active directory using PowerShell.

While playing with some stuff in my lab setup today, I got a requirement to have 100 test user accounts. I am not concerned much about the display name or any other properties of these test users and having names like user1, user2…user100 is enough in my case. I quickly looked around the options for doing this using PowerShell and finally settled with below approach as it seems much easy.

Since this is a very common requirement for anyone who are building and using their test labs for learning purpose, I thought of posting it here so that everyone can use it.

I used ActiveDirectory module that comes with Windows Server 2008 or above. It has cmdlet, New-ADUser, that simplifies the work. For this demonstration, I am creating user accounts from testuser1 to testuser100 with common password(“testme123”). I am also enabling the accounts after creation. All the new accounts will be created under the OU called LABAccounts at the room of my domain ad.techibee.com

You can copy paste the below code into a PowerShell window in your test lab and change –Path parameter to match your OU structure where you want to place the accounts and execute the script. You will see test accounts with in a minute.

Import-Module ActiveDirectory            
foreach($i in 1..100) {            
$AccountName = "TestUser{0}" -f $i            
$Password = Convertto-secureString -string "testme123" -AsPlainText            
New-ADUser -Name $AccountName -AccountPassword $Password -Path "OU=Labaccounts,DC=ad,DC=techibee,DC=com" -Enabled:$true            
            
}

Please note this above code is for lab purpose only where you want 100 or 1000 dummy user accounts for testing purpose. If you want to create users in production environment, you might want to set the required attribute values accordingly (like display name, telephone, etc).

{ 0 comments }