Monday, July 28, 2008

Get-QADGroupMember

A friend of mine posed the following question to me today at work:

Do you have any script to input a security group (GG or DLG, etc) and dump/extract the members (SAMID and e-mail address) into a file (txt or csv)?

As a matter of fact I do have a script to do that, actually it is more of a one liner. Here is the text. The text in red would be replaced with whatever group you wanted:

Get-QADGroupMember grp-wism-admins select samaccountname, displayname, email Export-Csv -Path groupsearch.csv –NoTypeInformation

One caveat. For this to run you have to install the AD cmdlets from Quest Software. These are available free from Quest. These are very powerful, useful cmdlets which make working with Active Directory a breeze in Powershell.

The software download is available here:
http://www.quest.com/powershell/activeroles-server.aspx

You'll want to download and install the 32 or 64 bit version based on your hardware. You'll also want to download the PDF based Administrator's Guide. It details the install, and also gives good examples of the Quest cmdlets. Help on the Quest cmdlets is also available through standard Powershell help methods. i.e. help get-qadgroupmember -full

Let me know if you have any questions or comments.

Thanks
Patrick

Saturday, July 26, 2008

Working with ACLS

One thing I frequently do is to migrate data from one server to another. With that data migration comes lots of clean up in the form of security permissions. I've been working on a way to use Powershell to get the security perms on a folder. Here is what I have so far. It works pretty well. Currently the data written to the screen, as well as to a spreadsheet called Output.xls.

Some more areas I want to add:
1. Make the spreadsheet an option by adding a switch /excel.
2. Make the spreadsheet activity part of a function call.

Let me know if you have any quesitons, or recommendations.

Here is the script text:
***********************************************************************************

# Inputbox - Prompt for path to scan
$x = New-Object -comobject MSScriptControl.ScriptControl
$x.language = "vbscript"
$x.addcode("function getInput() getInput = inputbox(`"Enter the path to scan.`",`"Path`") end function")
$path = $x.eval("getInput")
#delete old output file.
Remove-Item .\output.xls -force Out-Null
#Open a spreadsheet
#Region
$RowCount = 1

#Nice reference for the Excel activity.
#http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept06/hey0908.mspx
$a = New-Object -comobject Excel.Application
#$a.Visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item($RowCount,1) = "Path"
$c.Cells.Item($RowCount,2) = "Owner"
$c.Cells.Item($RowCount,3) = "Account and Perm"
#EndRegion
function scanACLs($strPath )
{
$owner = ($strPath Get-Acl select owner)
$ownerTemp = $owner.Owner
#$pathTemp = $strPath.PSChildName
$strPath Get-Acl select accesstostring fl Out-File -Force -Width 200 -filepath .\temp.txt
#Combine path and perms for output.
foreach ($i in(gc .\temp.txt))
{
#Split if string contains 'AccessToString'
if ($i.contains("AccessToString"))
{
$strTemp = (($i.split(":"))[1]).trim()
Write-Host "Owner:$ownerTemp Perms:$strTemp"
$script:RowCount += 1
$c.Cells.Item($RowCount,1) = $strPath
$c.Cells.Item($RowCount,2) = $ownerTemp
$c.Cells.Item($RowCount,3) = $strTemp
}
elseif ($i.length -gt 0)
{
$strTemp = $i.trim()
Write-Host "Owner:$ownerTemp Perms:$strTemp"
$script:RowCount += 1
$c.Cells.Item($RowCount,1) = $strPath
$c.Cells.Item($RowCount,2) = $ownerTemp
$c.Cells.Item($RowCount,3) = $strTemp
}
}
}
#Main
#This will go through the folder obtained in the Message Box at the launch of the script.
#The function scanACLS is called for each child item.
foreach ($i in(dir $path sort name))
{
Write-Host "Scanning "$path"\"$i
scanACLs($path+"\"+$i)
#
}
#Save the spreadsheet and make it visible once it is loaded with all of the data from the scanning.
$b.SaveAs("$pwd\output.xls")
$a.Visible = $True

Thursday, July 24, 2008

Powershell - Get AD User Info

Frequently during my daily work I need to gather information on users that are contained in our Active Directory listing.
This script is used to quickly gather information on a users home folder, SAM account name, their email address, and the size of their home folder.

I use this a lot when I am moving users home folders from one server to another. To save time I frequently have the line that gathers home folder size remarked out with #.

The user account names that I am searching for are contained in a text file called
accounts.txt. This file is contained in the same folder as this script. The output is sent to the screen as well as a log file called output.csv.


$userArray = @("SAMID,HomeDirectory,EmailAdress,HomeFolderSize")
$allUsers = gc .\accounts.txt
$tempArray = @()
function logfile($strData)
{
Out-File -filepath output.csv -inputobject $strData -append
}
function getAccountInfo
{
$strName = $currentUser
$strFilter = "(&(objectCategory=User)(samAccountName=$strName))"
#Get User AD info
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.Filter = $strFilter
$objPath = $objSearcher.FindOne()
$objUser = $objPath.GetDirectoryEntry()
[string]$folder = $objUser.homeDirectory
[string]$email = $objUser.mail
[string]$samID = $objUser.sAMAccountName
[string]$folderSize= getFolderSize($objUser.homeDirectory)
#$objUser.memberOf

$result = "$samID,$folder,$email,$folderSize"
$result #This causes the output to steam out, and be piped as the return from the function.
$folderSize = $null
$fs = $null
}
function getFolderSize($strPath)
{
$fs = New-Object -comobject Scripting.FileSystemObject
#Check validity of $strPath
if ($fs.FolderExists($strPath))
{
[double]$tempSize = ($fs.GetFolder($strPath).size) / 1024 / 1024
$tempSize = '{0:N}' -f[double]$tempSize
$tempSize
}
else
{
$tempSize = "Bad folder path!"
$tempSize
}
}
$header = "SAMID,HomeDirectory,EmailAdress,HomeFolderSize"
Out-File -filepath output.csv -inputobject $header
foreach ($currentUser in $allUsers)
{
$tempOutput = getAccountInfo $currentUser
$tempOutput
$userArray += [string[]]$tempOutput
logfile($tempOutput)
}


Let me know if you have any questions about this, or if it is helpful.

Thanks
Patrick