Speed Powershell Script Up

时间:2018-02-21 20:38:18

标签: powershell

我正在寻找加速我的Powershell脚本的方法。我有一个脚本,它根据.txt文件返回管理器员工ID和管理员名称,该文件具有该管理器下每个用户的samaccountnames。问题是列表很长,大约有1400多个名字,脚本需要永远运行。这是我的剧本。它的工作原理,只是想找到一种加快速度的方法:

cls
If (!(Get-Module -Name activerolesmanagementshell -ErrorAction SilentlyContinue))
{
Import-Module activerolesmanagementshell
}
Write-host $("*" * 75)
Write-host "*"
Write-host "*    Input file should contain just a list of samaccountnames - no header row."
Write-host "*"
Write-host $("*" * 75)

$File = Read-Host -Prompt "Please supply a file name"

If (!(test-path $File))
{
Write-host "Sorry couldn't find the file...buh bye`n`n"
exit
}

get-content $File | %{

$EmpInfo = get-qaduser -proxy -Identity $_ -IncludedProperties employeeid,edsva_SSCOOP_managerEmployeeID

# Check if we received back a Manager ID - if yes, get the Manager's name
# If not, set the Manager Name to "NONE" for output

If ($($EmpInfo.edsva_SSCOOP_managerEmployeeID).length -gt 2)
{

# Get the Manager's name from AD
$($EmpInfo.edsva_SSCOOP_managerEmployeeID)

$ManagerName = $(Get-QADUser -SearchAttributes @{employeeid=$($EmpInfo.edsva_SSCOOP_managerEmployeeID)} | select name).name

If (!$ManagerName)
{
$ManagerName = "NONE"
}

# Add the Manager name determined above (or NONE) to the properties we'll eventually output

$EmpInfo | Add-Member -MemberType NoteProperty -Name ManagerName -Value $ManagerName

}
Else
{
$EmpInfo.edsva_SSCOOP_managerEmployeeID = "NONE"
}

# Output user samaccountname edsva_SSCOOP_managerEmployeeID and ManagerName to a file

$EmpInfo | select samaccountname,edsva_SSCOOP_managerEmployeeID,ManagerName | export-csv "C:\Users\sfp01\Documents\Data_Deletion_Testing\Script_DisaUser_MgrEmpID\Disabled_Users_With_Manager.txt" -NoTypeInformation -Append

}  # End of file processing loop

1 个答案:

答案 0 :(得分:0)

好的,首先要做的事情是......要求用户输入文件名。给他们一个友好的友好对话框,不费吹灰之力。这是我手边的一个功能:

Function Get-FilePath{
[CmdletBinding()]
Param(
    [String]$Filter = "All Files (*.*)|*.*|Comma Seperated Values (*.csv)|*.csv|Text Files (*.txt)|*.txt",
    [String]$InitialDirectory = $home,
    [String]$Title)

    [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $InitialDirectory
    $OpenFileDialog.filter = $Filter
    $OpenFileDialog.Title = $Title
    [void]$OpenFileDialog.ShowDialog()
    $OpenFileDialog.filename
}

然后你可以这样做:

$File = Get-FilePath -Filter 'Text Files (*.txt)|*.txt|All Files (*.*)|*.*' -InitialDirectory "$home\Desktop" -Title 'Select user list'

这不会加快速度,只是提高生活质量。

其次,当窗口关闭时,您的“无法找到文件”消息将显示,因此运行脚本的人可能无法看到它。为此,我有一个函数,我用它来暂停带有消息的脚本。

Function Invoke-Pause ($Text){
    [reflection.assembly]::LoadWithPartialName('Windows.Forms')|out-null
    If($psISE){
        [Windows.Forms.MessageBox]::Show("$Text", "Script Paused", [Windows.Forms.MessageBoxButtons]"OK", [Windows.Forms.MessageBoxIcon]"Information") | ?{(!($_ -eq "OK"))}
    }Else{
        Write-Host $Text
        Write-Host "Press any key to continue ..."
        $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}

通过它,您可以向用户收到消息,然后关闭脚本以便用户知道发生了什么。此功能适用于PowerShell控制台以及PowerShell ISE。在控制台中,您会收到一条您定义的短信,然后是“按任意键继续...”消息,它会等待用户按一个键。在ISE中,它会弹出一个包含您的消息的窗口,并在继续之前等待用户单击“确定”按钮。你可以这样做:

If(!(Test-Path $File)){Invoke-Pause "Sorry couldn't find the file...buh bye";exit}

现在开始加快速度!

每位经理您有多名员工吗?那么为什么不止一次看经理呢?设置哈希表以跟踪您的经理信息,然后只有在哈希表中找不到它们时才查找它们。在你的循环声明$Managers作为一个只声明'NONE'='NONE'的哈希表之前,然后在循环中根据需要填充它,然后再引用它。

此外,您要为每个用户附加一个文件。这意味着PowerShell必须对文件进行文件锁定,写入文件,关闭文件,然后释放锁定...一遍又一遍......直接管道用户管道并写入文件一旦结束。

Function Get-FilePath{
[CmdletBinding()]
Param(
    [String]$Filter = "All Files (*.*)|*.*|Comma Seperated Values (*.csv)|*.csv|Text Files (*.txt)|*.txt",
    [String]$InitialDirectory = $home,
    [String]$Title)

    [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $InitialDirectory
    $OpenFileDialog.filter = $Filter
    $OpenFileDialog.Title = $Title
    [void]$OpenFileDialog.ShowDialog()
    $OpenFileDialog.filename
}

cls
If (!(Get-Module -Name activerolesmanagementshell -ErrorAction SilentlyContinue))
{
Import-Module activerolesmanagementshell
}
Write-host $("*" * 75)
Write-host "*"
Write-host "*    Input file should contain just a list of samaccountnames - no header row."
Write-host "*"
Write-host $("*" * 75)

$File = Get-FilePath -Filter 'Text Files (*.txt)|*.txt|All Files (*.*)|*.*' -InitialDirectory "$home\Desktop" -Title 'Select user list'

If (!(test-path $File))
{
Write-host "Sorry couldn't find the file...buh bye`n`n"
exit
}

$Managers = @{'NONE'='NONE'}
Get-Content $File | %{
    $EmpInfo = get-qaduser -proxy -Identity $_ -IncludedProperties employeeid,edsva_SSCOOP_managerEmployeeID
    Switch($EmpInfo.edsva_SSCOOP_managerEmployeeID){
        {$_.Length -lt 2} {$EmpInfo.edsva_SSCOOP_managerEmployeeID = 'NONE'}
        {$_ -notin $Managers.Keys} {
            $MgrLookup = Get-QADUser -SearchAttributes @{employeeid=$EmpInfo.edsva_SSCOOP_managerEmployeeID} |% Name
            If(!$MgrLookup){$MgrLookup = 'NONE'}
            $Managers.add($EmpInfo.edsva_SSCOOP_managerEmployeeID,$MgrLookup)
            }
    }
    Add-Member -InputObject $EmpInfo -NotePropertyName 'ManagerName' -NotePropertyValue $Managers[$EmpInfo.edsva_SSCOOP_managerEmployeeID] -PassThru
} | select samaccountname,edsva_SSCOOP_managerEmployeeID,ManagerName | Export-Csv "C:\Users\sfp01\Documents\Data_Deletion_Testing\Script_DisaUser_MgrEmpID\Disabled_Users_With_Manager.txt" -NoTypeInformation -Append