Powershell 在OU中的每台计算机上获取本地管理员帐户
我正在尝试获取administrators组中在其受尊敬的计算机上的所有用户帐户的列表,以及我们整个OU的列表。我发现一个脚本可以在一台计算机上显示这一点,但我想调用CSV文件以获取计算机名称,然后将结果输出到另一个CSV文件。以下是我正在使用的脚本:Powershell 在OU中的每台计算机上获取本地管理员帐户,powershell,active-directory,admin,administrator,ou,Powershell,Active Directory,Admin,Administrator,Ou,我正在尝试获取administrators组中在其受尊敬的计算机上的所有用户帐户的列表,以及我们整个OU的列表。我发现一个脚本可以在一台计算机上显示这一点,但我想调用CSV文件以获取计算机名称,然后将结果输出到另一个CSV文件。以下是我正在使用的脚本: Function Get-LocalGroupMembership { <# .SYNOPSIS Recursively list all members of a specified Local group.
Function Get-LocalGroupMembership {
<#
.SYNOPSIS
Recursively list all members of a specified Local group.
.DESCRIPTION
Recursively list all members of a specified Local group. This can be run against a local or
remote system or systems. Recursion is unlimited unless specified by the -Depth parameter.
Alias: glgm
.PARAMETER Computername
Local or remote computer/s to perform the query against.
Default value is the local system.
.PARAMETER Group
Name of the group to query on a system for all members.
Default value is 'Administrators'
.PARAMETER Depth
Limit the recursive depth of a query.
Default value is 2147483647.
.PARAMETER Throttle
Number of concurrently running jobs to run at a time
Default value is 10
.NOTES
Author: Boe Prox
Created: 8 AUG 2013
Version 1.0 (8 AUG 2013):
-Initial creation
.EXAMPLE
Get-LocalGroupMembership
Name ParentGroup isGroup Type Computername Depth
---- ----------- ------- ---- ------------ -----
Administrator Administrators False Domain DC1 1
boe Administrators False Domain DC1 1
testuser Administrators False Domain DC1 1
bob Administrators False Domain DC1 1
proxb Administrators False Domain DC1 1
Enterprise Admins Administrators True Domain DC1 1
Sysops Admins Enterprise Admins True Domain DC1 2
Domain Admins Enterprise Admins True Domain DC1 2
Administrator Enterprise Admins False Domain DC1 2
Domain Admins Administrators True Domain DC1 1
proxb Domain Admins False Domain DC1 2
Administrator Domain Admins False Domain DC1 2
Sysops Admins Administrators True Domain DC1 1
Org Admins Sysops Admins True Domain DC1 2
Enterprise Admins Sysops Admins True Domain DC1 2
Description
-----------
Gets all of the members of the 'Administrators' group on the local system.
.EXAMPLE
Get-LocalGroupMembership -Group 'Administrators' -Depth 1
Name ParentGroup isGroup Type Computername Depth
---- ----------- ------- ---- ------------ -----
Administrator Administrators False Domain DC1 1
boe Administrators False Domain DC1 1
testuser Administrators False Domain DC1 1
bob Administrators False Domain DC1 1
proxb Administrators False Domain DC1 1
Enterprise Admins Administrators True Domain DC1 1
Domain Admins Administrators True Domain DC1 1
Sysops Admins Administrators True Domain DC1 1
Description
-----------
Gets the members of 'Administrators' with only 1 level of recursion.
#>
[cmdletbinding()]
Param (
[parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('CN','__Server','Computer','IPAddress')]
[string[]]$Computername = $env:COMPUTERNAME,
[parameter()]
[string]$Group = "Administrators",
[parameter()]
[int]$Depth = ([int]::MaxValue),
[parameter()]
[Alias("MaxJobs")]
[int]$Throttle = 10
)
Begin {
$PSBoundParameters.GetEnumerator() | ForEach {
Write-Verbose $_
}
#region Extra Configurations
Write-Verbose ("Depth: {0}" -f $Depth)
#endregion Extra Configurations
#Define hash table for Get-RunspaceData function
$runspacehash = @{}
#Function to perform runspace job cleanup
Function Get-RunspaceData {
[cmdletbinding()]
param(
[switch]$Wait
)
Do {
$more = $false
Foreach($runspace in $runspaces) {
If ($runspace.Runspace.isCompleted) {
$runspace.powershell.EndInvoke($runspace.Runspace)
$runspace.powershell.dispose()
$runspace.Runspace = $null
$runspace.powershell = $null
} ElseIf ($runspace.Runspace -ne $null) {
$more = $true
}
}
If ($more -AND $PSBoundParameters['Wait']) {
Start-Sleep -Milliseconds 100
}
#Clean out unused runspace jobs
$temphash = $runspaces.clone()
$temphash | Where {
$_.runspace -eq $Null
} | ForEach {
Write-Verbose ("Removing {0}" -f $_.computer)
$Runspaces.remove($_)
}
} while ($more -AND $PSBoundParameters['Wait'])
}
#region ScriptBlock
$scriptBlock = {
Param ($Computer,$Group,$Depth,$NetBIOSDomain,$ObjNT,$Translate)
$Script:Depth = $Depth
$Script:ObjNT = $ObjNT
$Script:Translate = $Translate
$Script:NetBIOSDomain = $NetBIOSDomain
Function Get-LocalGroupMember {
[cmdletbinding()]
Param (
[parameter()]
[System.DirectoryServices.DirectoryEntry]$LocalGroup
)
# Invoke the Members method and convert to an array of member objects.
$Members= @($LocalGroup.psbase.Invoke("Members"))
$Counter++
ForEach ($Member In $Members) {
Try {
$Name = $Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null)
$Path = $Member.GetType().InvokeMember("ADsPath", 'GetProperty', $Null, $Member, $Null)
# Check if this member is a group.
$isGroup = ($Member.GetType().InvokeMember("Class", 'GetProperty', $Null, $Member, $Null) -eq "group")
If (($Path -like "*/$Computer/*")) {
$Type = 'Local'
} Else {$Type = 'Domain'}
New-Object PSObject -Property @{
Computername = $Computer
Name = $Name
Type = $Type
ParentGroup = $LocalGroup.Name[0]
isGroup = $isGroup
Depth = $Counter
}
If ($isGroup) {
# Check if this group is local or domain.
#$host.ui.WriteVerboseLine("(RS)Checking if Counter: {0} is less than Depth: {1}" -f $Counter, $Depth)
If ($Counter -lt $Depth) {
If ($Type -eq 'Local') {
If ($Groups[$Name] -notcontains 'Local') {
$host.ui.WriteVerboseLine(("{0}: Getting local group members" -f $Name))
$Groups[$Name] += ,'Local'
# Enumerate members of local group.
Get-LocalGroupMember $Member
}
} Else {
If ($Groups[$Name] -notcontains 'Domain') {
$host.ui.WriteVerboseLine(("{0}: Getting domain group members" -f $Name))
$Groups[$Name] += ,'Domain'
# Enumerate members of domain group.
Get-DomainGroupMember $Member $Name $True
}
}
}
}
} Catch {
$host.ui.WriteWarningLine(("GLGM{0}" -f $_.Exception.Message))
}
}
}
Function Get-DomainGroupMember {
[cmdletbinding()]
Param (
[parameter()]
$DomainGroup,
[parameter()]
[string]$NTName,
[parameter()]
[string]$blnNT
)
Try {
If ($blnNT -eq $True) {
# Convert NetBIOS domain name of group to Distinguished Name.
$objNT.InvokeMember("Set", "InvokeMethod", $Null, $Translate, (3, ("{0}{1}" -f $NetBIOSDomain.Trim(),$NTName)))
$DN = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $Translate, 1)
$ADGroup = [ADSI]"LDAP://$DN"
} Else {
$DN = $DomainGroup.distinguishedName
$ADGroup = $DomainGroup
}
$Counter++
ForEach ($MemberDN In $ADGroup.Member) {
$MemberGroup = [ADSI]("LDAP://{0}" -f ($MemberDN -replace '/','\/'))
New-Object PSObject -Property @{
Computername = $Computer
Name = $MemberGroup.name[0]
Type = 'Domain'
ParentGroup = $NTName
isGroup = ($MemberGroup.Class -eq "group")
Depth = $Counter
}
# Check if this member is a group.
If ($MemberGroup.Class -eq "group") {
If ($Counter -lt $Depth) {
If ($Groups[$MemberGroup.name[0]] -notcontains 'Domain') {
Write-Verbose ("{0}: Getting domain group members" -f $MemberGroup.name[0])
$Groups[$MemberGroup.name[0]] += ,'Domain'
# Enumerate members of domain group.
Get-DomainGroupMember $MemberGroup $MemberGroup.Name[0] $False
}
}
}
}
} Catch {
$host.ui.WriteWarningLine(("GDGM{0}" -f $_.Exception.Message))
}
}
#region Get Local Group Members
$Script:Groups = @{}
$Script:Counter=0
# Bind to the group object with the WinNT provider.
$ADSIGroup = [ADSI]"WinNT://$Computer/$Group,group"
Write-Verbose ("Checking {0} membership for {1}" -f $Group,$Computer)
$Groups[$Group] += ,'Local'
Get-LocalGroupMember -LocalGroup $ADSIGroup
#endregion Get Local Group Members
}
#endregion ScriptBlock
Write-Verbose ("Checking to see if connected to a domain")
Try {
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Root = $Domain.GetDirectoryEntry()
$Base = ($Root.distinguishedName)
# Use the NameTranslate object.
$Script:Translate = New-Object -comObject "NameTranslate"
$Script:objNT = $Translate.GetType()
# Initialize NameTranslate by locating the Global Catalog.
$objNT.InvokeMember("Init", "InvokeMethod", $Null, $Translate, (3, $Null))
# Retrieve NetBIOS name of the current domain.
$objNT.InvokeMember("Set", "InvokeMethod", $Null, $Translate, (1, "$Base"))
[string]$Script:NetBIOSDomain =$objNT.InvokeMember("Get", "InvokeMethod", $Null, $Translate, 3)
} Catch {Write-Warning ("{0}" -f $_.Exception.Message)}
#region Runspace Creation
Write-Verbose ("Creating runspace pool and session states")
$sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$runspacepool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host)
$runspacepool.Open()
Write-Verbose ("Creating empty collection to hold runspace jobs")
$Script:runspaces = New-Object System.Collections.ArrayList
#endregion Runspace Creation
}
Process {
ForEach ($Computer in $Computername) {
#Create the powershell instance and supply the scriptblock with the other parameters
$powershell = [powershell]::Create().AddScript($scriptBlock).AddArgument($computer).AddArgument($Group).AddArgument($Depth).AddArgument($NetBIOSDomain).AddArgument($ObjNT).AddArgument($Translate)
#Add the runspace into the powershell instance
$powershell.RunspacePool = $runspacepool
#Create a temporary collection for each runspace
$temp = "" | Select-Object PowerShell,Runspace,Computer
$Temp.Computer = $Computer
$temp.PowerShell = $powershell
#Save the handle output when calling BeginInvoke() that will be used later to end the runspace
$temp.Runspace = $powershell.BeginInvoke()
Write-Verbose ("Adding {0} collection" -f $temp.Computer)
$runspaces.Add($temp) | Out-Null
Write-Verbose ("Checking status of runspace jobs")
Get-RunspaceData @runspacehash
}
}
End {
Write-Verbose ("Finish processing the remaining runspace jobs: {0}" -f (@(($runspaces | Where {$_.Runspace -ne $Null}).Count)))
$runspacehash.Wait = $true
Get-RunspaceData @runspacehash
#region Cleanup Runspace
Write-Verbose ("Closing the runspace pool")
$runspacepool.close()
$runspacepool.Dispose()
#endregion Cleanup Runspace
}
函数获取LocalGroupMembership{
[cmdletbinding()]
Param(
[参数(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[别名(“CN”、“服务器”、“计算机”、“IP地址”)]
[string[]$Computername=$env:Computername,
[参数()]
[string]$Group=“Administrators”,
[参数()]
[int]$Depth=([int]::MaxValue),
[参数()]
[别名(“MaxJobs”)]
[int]$Throttle=10
)
开始{
$PSBoundParameters.GetEnumerator()| ForEach{
长篇大论$_
}
#区域额外配置
详细写入(“深度:{0}”-f$Depth)
#端区额外配置
#为Get RunspaceData函数定义哈希表
$runspacehash=@{}
#用于执行运行空间作业清理的函数
函数Get RunspaceData{
[cmdletbinding()]
param(
[切换]$等待
)
做{
$more=$false
Foreach($runspace中的$runspaces){
If($runspace.runspace.isCompleted){
$runspace.powershell.EndInvoke($runspace.runspace)
$runspace.powershell.dispose()
$runspace.runspace=$null
$runspace.powershell=$null
}ElseIf($runspace.runspace-ne$null){
$more=$true
}
}
If($more-和$PSBoundParameters['Wait'])){
开始睡眠-100毫秒
}
#清除未使用的运行空间作业
$temphash=$runspaces.clone()
$temphash |在哪里{
$\运行空间-eq$Null
}| ForEach{
详细写入(“删除{0}”-f$\计算机)
$Runspaces.remove($\ux)
}
}而($more-和$PSBoundParameters['Wait']))
}
#区域脚本块
$scriptBlock={
参数($Computer、$Group、$Depth、$NetBIOSDomain、$ObjNT、$Translate)
$Script:Depth=$Depth
$Script:ObjNT=$ObjNT
$Script:Translate=$Translate
$Script:NetBIOSDomain=$NetBIOSDomain
函数Get LocalGroupMember{
[cmdletbinding()]
Param(
[参数()]
[System.DirectoryServices.DirectoryEntry]$LocalGroup
)
#调用Members方法并转换为成员对象数组。
$Members=@($LocalGroup.psbase.Invoke(“成员”))
美元柜台++
ForEach($Members中的成员){
试一试{
$Name=$Member.GetType().InvokeMember(“Name”、'GetProperty'、$Null、$Member、$Null)
$Path=$Member.GetType().InvokeMember(“ADsPath”、'GetProperty'、$Null、$Member、$Null)
#检查此成员是否为组。
$isGroup=($Member.GetType().InvokeMember(“类”、'GetProperty'、$Null、$Member、$Null)-eq“组”)
If(($Path-like“*/$Computer/*”){
$Type='Local'
}Else{$Type='Domain'}
新对象PSObject-属性@{
Computername=$Computer
Name=$Name
Type=$Type
ParentGroup=$LocalGroup.Name[0]
isGroup=$isGroup
深度=$计数器
}
如果($isGroup){
#检查此组是本地组还是域组。
#$host.ui.WriteEverBoseline(“(RS)检查计数器:{0}是否小于深度:{1}”-f$Counter,$Depth)
如果($计数器-lt$深度){
如果($Type-eq‘Local’){
如果($Groups[$Name]-notcontains'Local'){
$host.ui.WriteEverBoseline((“{0}:获取本地组成员”-f$Name))
$Groups[$Name]+=,“本地”
#枚举本地组的成员。
获取LocalGroupMember$Member
}
}否则{
如果($Groups[$Name]-不包含“域”){
$host.ui.WriteEverBoseline((“{0}:获取域组成员”-f$Name))
$Groups[$Name]+=,“域”
#枚举域组的成员。
获取DomainGroupMember$Member$Name$True
}
}
}
}
}抓住{
$host.ui.WriteWarningLine((((“GLGM{0}”-f$\.Exception.Message))
}
}
}
函数Get DomainGroupMember{
[cmdletbinding()]
Param(
[参数()]
$DomainGroup,
[参数()]
[字符串]$NTName,
[参数()]
[字符串]$blnNT
)
试一试{
如果($blnNT-eq$True){
#将组的NetBIOS域名转换为可分辨名称。
$objNT.InvokeMember(“Set”,“InvokeMethod”,“Null”,“Translate,(3,(“{0}{1}”-f$NetBIOSDomain.Trim(),$NTName)))
$DN=$objNT.InvokeMember(“Get”、“InvokeMethod”、$Null、$Translate,1)
$ADGroup=[ADSI]
import-csv T:\computers.csv | Get-LocalGroupMembership
import-csv T:\computers.csv | Get-LocalGroupMembership | Where Name | Export-CSV t:\LocalAdmins.csv