获取旧版Exchange服务器上的用户的Active Directory属性

时间:2010-03-17 19:56:48

标签: powershell scripting active-directory exchange-server

我想在Exchange 2003服务器上创建用户的CSV文件,并在其AD帐户中包含一些属性。特别是,我想使用RecipientTypeDetails = LegacyMailbox为用户提取某些AD值。

我尝试了一些不同的方法来定位和过滤(ldapfilter,filter,objectAttribute等)这些用户,但收效甚微。 Exchange 2003 PowerPUI的PowerPack很有帮助,但权限问题和使用Exchange_Mailbox类并不是我想要克服的挑战。

我终于能够创建一个工作脚本,但速度非常慢。我在下面创建的脚本目前正在运行,但它有望完成大约4个多小时。我正在寻找提高脚本效率或以更快的方式获取此数据的建议。这是脚本:

$ADproperties = 'City','Company','department','Description','DistinguishedName','DisplayName','FirstName','l','LastName','msExchHomeServerName','NTAccountName','ParentContainer','physicaldeliveryofficename','SamAccountName','useraccountcontrol','UserPrincipalName'
get-user -ResultSize Unlimited -ignoredefaultscope -RecipientTypeDetails LegacyMailbox | foreach {Get-QADUser $_.name -DontUseDefaultIncludedProperties -IncludedProperties $ADproperties} | select $ADproperties | epcsv C:\UserListBuilder\exchUsers.csv -notype

非常感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:0)

我使用我已经创建的脚本解决了这个挑战,该脚本将CSV文件与AD中的属性合并。基本上我使用Get-Mailbox生成所有Exchange 2003用户的CSV列表,然后使用该列表作为Get-QADuser的输入来提取我需要的AD属性,并且无法使用其他cmdlet。 Merge-Object和Export-CSV功能是从互联网上的其他用户那里找到的,都是非常方便的功能。以下是该脚本的副本:

Function Merge-Object($Base, $Additional)
{
ForEach ($Property in $($Additional | Get-Member -Type Property, NoteProperty))
{
    $Base | Add-Member -MemberType NoteProperty -Name $Property.Name -Value $Additional.$($Property.Name) -ErrorAction SilentlyContinue
}
Return $Base
}
Function Export-CSV
{
[CmdletBinding(DefaultParameterSetName='Delimiter',
SupportsShouldProcess=$true, ConfirmImpact='Medium')]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)]
[System.Management.Automation.PSObject]
${InputObject},

[Parameter(Mandatory=$true, Position=0)]
[Alias('PSPath')]
[System.String]
${Path},

#region -Append (added by Dmitry Sotnikov)
[Switch]
${Append},
#endregion 

[Switch]
${Force},

[Switch]
${NoClobber},

[ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32','BigEndianUnicode','Default','OEM')]
[System.String]
${Encoding},

[Parameter(ParameterSetName='Delimiter', Position=1)]
[ValidateNotNull()]
[System.Char]
${Delimiter},

[Parameter(ParameterSetName='UseCulture')]
[Switch]
${UseCulture},

[Alias('NTI')]
[Switch]
${NoTypeInformation})

begin
{
# This variable will tell us whether we actually need to append
# to existing file
$AppendMode = $false

try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
    $PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Csv',
    [System.Management.Automation.CommandTypes]::Cmdlet)


    #String variable to become the target command line
    $scriptCmdPipeline = ''

    # Add new parameter handling
    #region Dmitry: Process and remove the Append parameter if it is present
    if ($Append) {

        $PSBoundParameters.Remove('Append') | Out-Null

if ($Path) {
if (Test-Path $Path) {        
    # Need to construct new command line
    $AppendMode = $true

    if ($Encoding.Length -eq 0) {
    # ASCII is default encoding for Export-CSV
    $Encoding = 'ASCII'
    }

    # For Append we use ConvertTo-CSV instead of Export
    $scriptCmdPipeline += 'ConvertTo-Csv -NoTypeInformation '

    # Inherit other CSV convertion parameters
    if ( $UseCulture ) {
    $scriptCmdPipeline += ' -UseCulture '
    }
    if ( $Delimiter ) {
    $scriptCmdPipeline += " -Delimiter '$Delimiter' "
    } 

    # Skip the first line (the one with the property names) 
    $scriptCmdPipeline += ' | Foreach-Object {$start=$true}'
    $scriptCmdPipeline += '{if ($start) {$start=$false} else {$_}} '

    # Add file output
    $scriptCmdPipeline += " | Out-File -FilePath '$Path' -Encoding '$Encoding' -Append "

    if ($Force) {
    $scriptCmdPipeline += ' -Force'
    }

    if ($NoClobber) {
    $scriptCmdPipeline += ' -NoClobber'
    }   
}
}
} 



$scriptCmd = {& $wrappedCmd @PSBoundParameters }

if ( $AppendMode ) {
# redefine command line
$scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
    $scriptCmdPipeline
    )
} else {
# execute Export-CSV as we got it because
# either -Append is missing or file does not exist
$scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
    [string]$scriptCmd
    )
}

# standard pipeline initialization
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)

} catch {
throw
}

}

process
{
try {
    $steppablePipeline.Process($_)
} catch {
    throw
}
}

end
{
try {
    $steppablePipeline.End()
} catch {
    throw
}
}
<#

.ForwardHelpTargetName Export-Csv
.ForwardHelpCategory Cmdlet

#>
}
###################################################################################################################################
#   Script
###################################################################################################################################
# Get Start Time
$startDTM = (Get-Date)
$ADproperties = 'FirstName','LastName','userAccountControl','physicaldeliveryofficename','l','City','UserPrincipalName','NTAccountName','SamAccountName','ParentContainer','Description','msExchHomeServerName'
#$CSVdirectory = "C:\UserListBuilder\CSV\Exch2003\*.*"  # Directory containing Exchange directory export CSV files, include *.*
$csv = "C:\UserListBuilder\CSV\Exch2003\ex03.csv"
$Outputfilename = "C:\UserListBuilder\Exchange2003-ADInfo.csv"

# Create a file of the legacy mailboxes
Get-Mailbox -ignoredefaultscope -ResultSize 'Unlimited' | where { $_.'RecipientTypeDetails' -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientTypeDetails]'LegacyMailbox' } | select 'DisplayName','SamAccountName','UserPrincipalName' | epcsv $csv -notype

$CurrentFile = Import-Csv $csv

foreach($Row in $CurrentFile)
{
$CurrentUser = $Row.'UserPrincipalName'

$CurrentUserADinfo = Get-QADUser -identity "$CurrentUser" -DontUseDefaultIncludedProperties -IncludedProperties $ADproperties | select-object $ADproperties
Merge-Object $Row $CurrentUserADinfo
$Row | Export-CSV -Path $Outputfilename -Append -NoTypeInformation
}

# Get End Time
$endDTM = (Get-Date)

# Echo Time elapsed
"Elapsed Time: $(($endDTM-$startDTM).totalseconds) seconds"