[玩转系统] 更好的 PowerShell 属性
作者:精品下载站 日期:2024-12-14 08:07:16 浏览:14 分类:玩电脑
更好的 PowerShell 属性
我最近和我的朋友 Gladys Kravitz 谈论了她使用 Active Directory 和 DirectorySearcher 对象编写的一些 PowerShell 脚本。由于多种原因,远程服务器管理工具 (RSAT) 中的 Active Directory 模块不是一个选项。但那很好。 Gladys 是一位经验丰富的 AD 管理员和 PowerShell 脚本编写者。尽管如此,她对命令的输出仍有疑问,这导致了一些有趣的工作,您可能会发现这些工作很有价值。尽管我将讨论特定的对象类型,但您可以将几个原则应用于 PowerShell 脚本编写。
搜索结果属性
让我们从一些 PowerShell 代码开始,使用 DirectorySearcher 对象查找用户帐户。
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.filter ="(&(objectcategory=person)(objectclass=user))"
$searcher.FindOne().Properties
DirectorySearcher 具有 FindOne() 和 FindAll() 方法。生成的对象具有 Properties 属性。
您可以通过多种方式使用它。
New-Object -typename PSObject -property $searcher.FindOne().Properties | Select Name,Description,WhenChanged
将值的格式放在一边,请注意属性名称。功能齐全,但外观不专业。这始终是一个选择。
New-Object -typename PSObject -property $searcher.FindOne().Properties |
Select-Object @{Name="Name";Expression = {$_.name}},
@{Name="Description";Expression = {$_.Description}},
@{Name="WhenChanged";Expression = {$_.WhenChanged}}
或者,您可以使用类型名称定义自定义对象并使用自定义格式文件。但这是一项繁重的工作,而且不灵活。
这是创建对象的另一种方法,但具有正确大小写的属性名称。
$r = $searcher.FindOne()
$r.Properties.GetEnumerator() |
Where-Object { $_.key -match "Name|Description|WhenChanged|memberof|logoncount" } |
ForEach-Object -Begin {
#initialize an empty hashtable
$h = @{}
} -Process {
#convert to title case
$n = [cultureinfo]::CurrentCulture.TextInfo.ToTitleCase($_.name.tolower())
if ($_.value.count -gt 1) {
#get the array of values
$v = $_.value
}
else {
#get the single value
$v = $_.value[0]
}
#add the property name and value to the hashtable
$h.Add($n, $v)
} -End {
#create a custom object from the hashtable
[pscustomobject]$h
}
在这种特殊情况下,我要格式化的对象是 DirectoryServices.ResultCollection,它本质上是一个哈希表,因此需要不同的方法。 GetEnumerator() 方法将集合中的每个元素写入具有 Key 和 Value 属性的对象。我的示例是过滤特定“属性”的键。
然后将过滤后的对象通过管道传送到 ForEach-Object。在管道中处理任何对象之前,我初始化一个空的哈希表。接下来,对于每个过滤结果,我将名称(“key”的别名)转换为标题大小写。为此,我总是在调用该方法之前将字符串全部小写。此重新格式化的名称和相应的值将添加到哈希表中。处理完所有内容后,我将哈希表转换为自定义对象。
这是有希望的,但需要更加灵活。 ForEach-Object 结构与采用管道输入的高级 PowerShell 函数的格式相同。换句话说,我有一个原型。
创建配置数据
我的想法是获取 DirectorySearcher 结果并创建一个自定义对象,用格式正确的名称和值替换属性名称。但在查看输出时,我想要的不仅仅是标题大小写。 “Logoncount”的格式可能看起来更好,如“LogonCount”。我更喜欢 SamAccountName。我想用格式正确的名称替换传入的属性名称。我需要按照我想要的方式格式化所有可能的属性名称的列表。因为我知道我最终会希望将此列表用作哈希表,所以我将创建一个配置数据文件,稍后可以将其与 Import-PowerShellDataFile 一起使用。
下面是根据对象类型生成不同配置数据文件的 PowerShell 脚本。
#requires -version 5.1
<# Create-ADPropertyFile.ps1
proof-of-concept code to create an Active Directory property configuration data file
.\Create-ADPropertyFile.ps1 -Filter "(&(objectclass=organizationalunit)(Name=Employees))" -FilePath .\adou.psd1
.\Create-ADPropertyFile.ps1 Group -FilePath .\adgroup.psd1
#>
[cmdletbinding(SupportsShouldProcess, DefaultParameterSetName = "byType")]
Param(
[Parameter(Position = 0, ParameterSetName = "byType")]
[ValidateSet("User", "Group", "Computer", "OU")]
[string]$ObjectType = "User",
[Parameter(HelpMessage = "Specify an LDAP search filter to a template object.", ParameterSetName = "byFilter")]
[ValidateNotNullOrEmpty()]
[string]$Filter,
[Parameter(Mandatory, HelpMessage = "Specify the filename and path to the psd1 file.")]
[ValidateScript({ Test-Path (Split-Path $_) })]
[string]$FilePath
)
if ($pscmdlet.ParameterSetName -eq "byType") {
Switch ($ObjectType) {
"User" { $filter = "(&(objectcategory=person)(objectclass=user))" }
"Group" { $filter = "(Objectclass=group)" }
"Computer" { $filter = "(objectclass=computer)" }
"OU" { $filter = "(objectclass=organizationalunit)" }
}
}
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.filter = $filter
#don't need values from the search
$searcher.PropertyNamesOnly = $true
$searcher.FindOne().Properties.GetEnumerator() | Sort-Object -Property Key |
ForEach-Object -Begin {
#initialize a list
$list = [System.Collections.Generic.List[string]]::new()
$list.add("@{")
} -Process {
$value = [cultureinfo]::CurrentCulture.TextInfo.ToTitleCase($($_.key.ToLower()))
#add each property to the list
$List.Add("$($_.key) = '$value'")
} -End {
#close the psd1
$list.Add("}")
}
#save the list to a file
$list | Out-File -FilePath $FilePath
#edit psd1 file with your desired formatting
默认过滤器将找到第一个匹配结果。但是,DirectorySearcher 将仅返回已定义的属性名称。您可能希望创建一个模板对象,其中包含您打算使用的已定义的所有属性,然后使用自定义 LDAP 过滤器构建属性文件到那个物体。
我将使用该脚本为用户对象创建 psd1 文件。
c:\scripts\Create-ADPropertyFile.ps1 -ObjectType User -FilePath c:\scripts\aduser.psd1
我可以编辑文件并调整属性名称。
@{
accountexpires = 'AccountExpires'
admincount = 'AdminCount'
adspath = 'AdsPath'
badpasswordtime = 'BadPasswordTime'
badpwdcount = 'BadPwdCount'
cn = 'CN'
codepage = 'CodePage'
countrycode = 'CountryCode'
department = "Department"
description = 'Description'
displayname = "DisplayName"
distinguishedname = 'DistinguishedName'
dscorepropagationdata = 'DscorePropagationData'
givenname = "GivenName"
instancetype = 'InstanceType'
iscriticalsystemobject = 'IsCriticalSystemObject'
lastlogoff = 'LastLogoff'
lastlogon = 'Lastlogon'
lastlogontimestamp = 'LastLogonTimestamp'
logoncount = 'LogonCount'
logonhours = 'LogonHours'
memberof = 'MemberOf'
name = 'Name'
objectcategory = 'ObjectCategory'
objectclass = 'ObjectClass'
objectguid = 'ObjectGuid'
objectsid = 'ObjectSid'
primarygroupid = 'PrimaryGroupId'
pwdlastset = 'PwdlastSet'
samaccountname = 'SamAccountName'
samaccounttype = 'SamAccountType'
sn = "Surname"
title = "Title"
useraccountcontrol = 'UserAccountcontrol'
usnchanged = 'UsnChanged'
usncreated = 'UsnCreated'
whenchanged = 'WhenChanged'
whencreated = 'WhenCreated'
}
}
如果您知道其他 LDAP 属性名称,则可以手动添加它们。最后一步是使用该文件。
优化广告搜索结果
我们倾向于避免在 PowerShell 中使用单一命令。相反,我们想利用管道。我有使用 DirectorySearcher 来查找对象的代码。
我想利用这些结果并优化属性名称。
Function Optimize-ADSearchResult {
[cmdletbinding()]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
HelpMessage = "This should be the input from an ADSearcher FindOne() or FindAll() method."
)]
[System.DirectoryServices.SearchResult]$InputObject,
[Parameter(
Mandatory,
HelpMessage = "Enter the path to the psd1 file with your property names. See Create-ADPropertyFile."
)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Path $_ })]
[ValidatePattern('\.psd1$')]
[string]$ConfigurationData,
[Parameter(HelpMessage = "Specify a custom type name, like CorpADUser. You might add this if using a custom format file or type extensions.")]
[ValidateNotNullOrEmpty()]
[string]$TypeName
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
#import the configuration data
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Importing configuration data from $(Convert-Path $ConfigurationData)"
$PropertyData = Import-PowerShellDataFile -Path $ConfigurationData
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing input"
$InputObject.properties.GetEnumerator() |
ForEach-Object -Begin {
$new = [ordered]@{ }
if ($TypeName) {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using typename $TypeName"
$new.Add("PSTypename", $TypeName)
}
} -Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing property $($_.key)"
#Get formatted property name from configuration data
if ($PropertyData.Contains($_.key)) {
$name = $PropertyData["$($_.key)"]
}
else {
$name = $_.key
}
if ($_.value.count -gt 1) {
$value = $_.value
}
else {
$value = $_.value[0]
}
$new.Add($name, $value)
} -End {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Creating output"
New-Object -TypeName psobject -Property $new
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
}
该函数查看每个搜索结果并尝试匹配配置数据中的属性名称。如果找到匹配项,就会使用它。否则,PowerShell 将使用原始属性名称。
我可以将所有属性名称哈希表存储在函数中,但这会增加复杂性和不必要的长度。如果我需要添加属性,我必须编辑该函数。将数据与实现它的代码分开要好得多。我的函数是使用配置数据的一个很好的例子。
我可以获取搜索结果,使用此功能对其进行优化,然后选择我需要的内容。
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.filter = "(&(objectcategory=person)(objectclass=user)(department=sales))"
$searcher.FindAll() |
Optimize-ADSearchResult -ConfigurationData C:\scripts\aduser.psd1 |
Select-Object -property DistinguishedName,Givenname,Surname,Description,Title
概括
这篇文章中发生了很多事情——许多移动部分,可能还有一些新命令。我希望您能检查一下代码,并至少在脑子里走一遍。请随时留下评论和问题。
- 上一篇:[玩转系统] 敞开心扉
- 下一篇:[玩转系统] 按您的方式使用 PowerShell
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag