Archive

Archive for the ‘Active Directory’ Category

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: 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: Move Computer accounts from default container to specific OU

February 18, 2012 9 comments

Whenever a computer is added to a windows domain, by default account will get created under Computers container. It is located right below the domain name in dsa.msc. The pull of it is, <domainName>\Computers.

Today one of my friend has asked to know if there any quick script using which he can move all computers from default computers container to OU of his choice in same domain. Since I don’t have a script already authored for this purpose, I quickly made the below.

This is a very basic version of computer accounts movement script. There might be some conditions processing like if name contains XYZ move to one OU or if name contains ABC move to different OU. You can accommodate such conditions in this script if you have little powershell knowledge(or let me know I can help you given some time).

Here is the code.

[cmdletbinding()]            

param (
[parameter(mandatory=$true)]
$TargetOU
)            

Import-Module ActiveDirectory
$Domain = [ADSI]""
$DN=$domain.distinguishedName
$SourcePath = "CN=Computers," + $DN
$Computers = Get-ADComputer -Filter * -SearchBase $SourcePath
if(!$Computers) {
 write-host "No Computers are found in default container"
 return
}
foreach ($Computer in $Computers) {
 if(!(Move-ADObject $Computer -TargetPath $TargetOU)) {
  $Status = "SUCCESS"
 } else {
  $Status = "FAILED"
 }
 $OutputObj = New-Object -TypeName PSobject
 $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.Name.tostring()
 $OutputObj | Add-Member -MemberType NoteProperty -Name SourcePath -Value $SourcePath
 $OutputObj | Add-Member -MemberType NoteProperty -Name DestinationPath -Value $TargetOU
 $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Status
 $OutputObj
}

 

When I executed this script in my test domain for testing purpose it went fine and generated below output. This script is not depending on any external modules/cmdlets like quest tools. I uses ActiveDirectory module which comes with RSAT(or windows 2008 domain controllers). Needless to say that you need ADWS(active directory web services) installed if all your domain controllers are Windows 2003. This is not required if atleast one DC is having windows 2008 R2 OS where ADWS is default.

Output:

PowerShell: How to get nested Active Directory group members

January 2, 2012 7 comments

This post helps you to understand how to query nested group members using powershell. The MS given ActiveDirectory powershell module doesn’t provide a direct way to get all the members part of a security group. This information is useful because you can know who all will get permissions granted to a particular security group if the security group has sub groups inside it. If there is just one or two levels of sub groups, then maybe we can spend time and write code for querying those groups as well by parsing their names. But how we can handle the situation where we don’t know how many sub groups the group we are querying has and how many levels are there?

To address this requirement I have written a small powershell function that helps you to get all direct and indirect members of a security group in active directory.

function Get-ADNestedGroupMembers {
[cmdletbinding()]
param (
[String] $GroupName
)            

import-module activedirectory
$Members = Get-ADGroupMember -Identity $GroupName
$members | % {
    if($_.ObjectClass -eq "group") {
        Get-ADNestedGroupMembers -GroupName $_.distinguishedName
    } else {
        return $_.distinguishedname
    }
}            

}

In this code I am using Get-ADGroupMember cmdlet which is part of activedirectory module. This code uses recursive function call to query group members when a sub group is found.

Usage:

Hope this helps… please feel free to post in comments section if you have any questions. This script can be enhanced to display objects of a particular type — for example, only computers, only users etc. I am doing it here …but let me know if you have the requirement, I will add the code for that as well.

You can export the output to a file using below command.

Get-ADNestedGroupMembers -GroupName "Test1" | out-file -Filepath c:\temp\test1.txt

 

Hope this helps…

PowerShell: Adding a Domain Group to local administrators group on remote computer

Adding domain groups to local administrators group on remote computers(servers/workstations) is most common activity any system administrator do. I got similar task today and realized that I don’t have a PowerShell function to do. We know it is simple and can build command on fly, but having a function is much more useful. So, I have written below function and added to my techibee module(will publish this soon).

This script takes three arguments. 1) ComputerName — on which you want to do this operation. 2)GroupName — that you want to add to the local administrators group of remote computer 3) DomainName — an optional parameter using which you can pass the domain name if the group you are adding belongs to different domain that of your computer is currently in.

function Add-DomainGroupToLocalAdministrator {
param (
[parameter(Mandatory = $true)]
$ComputerName,            

[parameter(Mandatory = $true)]
$GroupName,            

$DomainName
)            

if(!($DomainName)) {
    Import-Module ActiveDirectory
    $DomainName = (Get-AdDomain).DNSRoot.ToString()
}            

try {            

    $AdminGroup = [ADSI]("WinNT://$ComputerName/Administrators,Group")
    $AdminGroup.Add("WinNT://$DomainName/$GroupName,Group")
    Write-host "Successfully Added $GroupName to local administrators group of $computerName"            

}
catch {
    Write-Error $_
}            

} 

Hope this helps…

How to get Group Policy permissions using powershell

December 21, 2011 Leave a comment

Using PowerShell, we can query who has permissions to a given GPO or a list of GPOs. We can do this either using Quest Active Roles cmdlets or by using native cmdlets that comes along with Windows 7 installation. In this post, I am going to demonstrate and show you the native method. To use the native method, you must be running one of the following:

  • Windows Server 2008 R2 on a domain controller
  • Windows Server 2008 R2 on a member server that has the GPMC installed
  • Windows® 7 with Remote Server Administration Tools (RSAT) installed. (RSAT includes the GPMC and the Group Policy cmdlets)

GPMC(or RSAT) installation also installs a powershell module called grouppolicy using which we can query the GPOs. Before start dealing with GPOs, we should import this module by using import-module GroupPolicy command.

Below is the sample code that helps you get permissions of a give a GPO.

function Get-GPOPermissions {            

param($GpoName)
import-module GroupPolicy            

$permsobj = Get-GPPermissions -Name $GPOName -All
foreach ($perm in $permsobj) {            

    $obj = New-Object -TypeName PSObject -Property @{
   GPOName  = $GPOName
   AccountName = $($perm.trustee.name)
        AccountType = $($perm.trustee.sidtype.tostring())
        Permissions = $($perm.permission)
 }
$obj | Select GPOName, AccountName, AccountType, Permissions            

}
}

Below is the sample output:

Hope this helps. I will continue writing some GPO related scripts in coming days.

 

 

How to Get SCOM Root Management server name using Powershell

December 20, 2011 1 comment

In this post you will learn how to query SCOM RMS server name of a specific SCOM group using powershell script.

In all my SCOM scripts that I wrote so far, I hardcoded the SCOM RMS server name. Recently I came across a situation where RMS role is moved to another management server in same SCOM group. With this change, obviously all my scripts will fail because the hard coded server is not a RMS server anymore and it has no intelligence to redirect my query to the current RMS sever.

That means we should have a dynamic way using which we can get RMS server automatically from some reliable source. SCOM installations creates a SCP(Service Connection Point) in Active directory for each SCOM group. So now I will show you how to query this SCP using powershell and get the RMS server name.

We can either choose to use build-in Activedirectory module or Quest AD Cmdlets to get information. The below code is based on activedirectory module which is available with Windows 2008 and Windows 7.

function Get-ScomRMSServer {            

Import-Module ActiveDirectory
$Domainname = (Get-ADDomain).DistinguishedName.tostring()
$SCOMObj = Get-ADObject -Filter "Name -eq 'SDKServiceSCP'" -SearchBase $domainname `
-Properties ServiceDNSName, ServiceClassName
$SCOMObj | select serviceclassname, serviceDNSName            

}

Thanks to my colleague(Deepesh) who helped with finding this.

 

Fix: Live Communications Server tab is not showing up in Active Directory Users and Computers MMC(dsa.msc)

November 17, 2011 2 comments

While having some discussion with my wife today, I came across an interesting scenario where “Active Directory Users and Computers” MMC is not showing the “Live Communications Server” tab in user properties though the LCS administrator tools are installed. I searched about same problem in internet and looks like many people have already experienced this. For some, enabling the “advanced features” option in dsa.msc MMC fixed the issue and some people installed the console on XP computers to work around the problem.

In the particular case where my wife did the troubleshooting, she found that LCS administrator tools are of 32-bit version and they were installed on a 64-bit OS server. So, what is the problem? 64-bit OS supports 32-bit right? what is the problem?.

The problem is that, when you launch dsa.msc MMC from run command, it will fire-up 64-bit version of MMC which looks like has some troubles in taking with 32-bit version of LCS tools. Hence, it is not loading the LCS related tabs in the properties of any user accounts.

To work around this problem, one can open dsa.msc in 32-bit mode by just simply typing the below command.

dsa.msc -32

You can use the similar trick to launch any MMC in 32-bit mode. After opening, just look the process name in task manager, you will find mmc.exe*32 which indicates a 32-bit process name. You will find normal mmc.exe if you run mmc without -32 switch.

I somehow felt this is interested topic every systemadmin should aware. Hence authored this post.

Hope this helps. Happy learning…

PowerShell: How to know the originating DC of a Active Directory object

November 11, 2011 Leave a comment

Originating DC means the Domain controller on which the object is created first. From the originating DC, the changes will replicate to other DCs in the domain. Some times this information is useful/crucial to know where exactly the object is created. This helps is troubleshooting AD replication related issues and sometimes in forensic investigation.

When ever a object is created in active directory, it stores the originating DC name in the meta data of that object. Meta data is something which we can not see from the general AD management tools like dsa.msc or adssite.msc. To view meta data, either we need to use repadmin or the dotnet object. You all know how to use repadmin so in this post I will give you a powershell script which displays the metadata of a given object.

$Domain = "techibee.com"
$objectDN = "cn=user1,cn=users,dc=techibee,dc=com"
$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$domain)
$dc = [System.DirectoryServices.ActiveDirectory.DomainController]::findOne($context)
$meta = $dc.GetReplicationMetadata($objectDN)
$meta.values

The above script takes two arguments, domain name and object DN and lists all the attributes and their originating DC names. Hope this helps…

 

Slow login issues due to Group Policy Preferences

September 8, 2011 Leave a comment

Have you started using Group Policy Preferences lately to manage your Windows 7 and Windows 2008 computers? It is possible that Group Policy Preferences can cause increase in login times in your environment if security groups are used for targeting preferences. For example, you may be mapping drives based on user security group membership(ex: sales, finance, etc). Per AskDS, when a security group is used for targeting a group policy preference setting, the computer has to make several round trips to domain controllers to verify the user group membership. This trip time depends on the kind of connectivity you have to domain controllers and the load of DC. If you are on a Wan link, the trip time may be even more. The windows 7/2008 computer won’t allow you to complete the login until this preference setting is evaluated and applied. In such graces the logon time will increase drastically which is a very bad experience for end users.

The AskDS team suggested using Organization Units instead of security groups for targeting. Usage of OUs will reduce the trips to domain controllers as the GPPs have to just parse the DN text of computer/user account to verify if a setting is applicable or not.

After reading the AskDS article, I wondered why they(MS) didn’t use security tokens for evaluating computer/user group membership at the time of processing the target. It is very easy and less traffic to domain controllers. It makes sense. Isn’t it?

I question was answered in very short time in the form of another AskDS article.  They exactly implemented what I felt. MS release hotfix(http://support.microsoft.com/kb/2561285) which injects this nice feature into Group Policy Preferences which can reduce the user logon times and computer startup times(if you are using security group targeting in computer GPPs).

So, if you are using Group Policy Preferences in your organization, then make sure that all your Windows 7/2008 computers have this hotfix. Otherwise one or other day you will end up looking for it when you users keep complaining about slow login issues.