Windows 筛选器获取Powershell中“Name-notlike”所在的ADComputer

Windows 筛选器获取Powershell中“Name-notlike”所在的ADComputer,windows,powershell,active-directory,Windows,Powershell,Active Directory,我的目标是获得一个不遵循whenCreated属性命名约定的AD计算机对象列表。我正在尝试使用以下PowerShell函数导出HTML文件: function get_bad_names { $result = Get-ADComputer -searchbase $OU -Filter {Name -notlike 'name1' -and Name -notlike 'name2' -and Name -notlike 'name3'} -Proper

我的目标是获得一个不遵循whenCreated属性命名约定的AD计算机对象列表。我正在尝试使用以下PowerShell函数导出HTML文件:

function get_bad_names
{
$result = Get-ADComputer -searchbase $OU
-Filter {Name -notlike 'name1' -and 
         Name -notlike 'name2' -and
         Name -notlike 'name3'} 
-Properties whenCreated | sort whenCreated

$result | ConvertTo-Html | Out-File $dir\badnames.html
}

get_bad_names
是否有一种更优雅的方式来构造名称筛选行?我们有40多行不同的名字。换句话说,我的剧本中有40多行写着名字——不像‘名字’——还有

理想情况下,我希望代码从文本文件中读取并导出相同的结果


仅供参考:此函数可以工作,但编写得并不理想。如有任何建议,将不胜感激

您可以使用Select Object使用正则表达式进行筛选,但是您应该使用-filter*获得OU中的所有计算机,这可能会使您的网络紧张。我会进行筛选,如果需要更多属性,请仅为匹配项再次运行Get Computer:

Get-ADComputer -searchbase $OU -Filter * |
? { $_.name -match "name\d{1,2}" } | # Match if string "name" is followed one or two digits
Get-ADComputer -property * # Get all properties for the computers if needed

如果要筛选查询,请构造LDAP筛选器:

# Define the names to exclude
$NamesToExclude = "Name1","Name2","Name3"
# Turn them into LDAP clauses in the form of "(!(Name=Name1))"
$LDAPClauses = $NamesToExclude |ForEach-Object {
    '(!(Name={0}))' -f $_
}
# Create a single query filter string with all the clauses from above
$LDAPFilter = "(&$LDAPClauses)"

$result = Get-ADComputer -LDAPFilter $LDAPFilter -SearchBase $OU -Properties whenCreated |Sort-Object whenCreated
是否有一种更优雅的方式来构造名称筛选行

不完全是。在ActiveDirectory模块中使用命令的-Filter参数时,运算符集相当有限,因为它必须将它们全部转换为LDAP筛选器

但是,您可以这样做:

$ExcludedPatterns = 'Name1', 'Name2', 'Name3'
$ComputerFilter = foreach ($Pattern in $ExcludedPatterns) { "(Name -notlike '$Pattern')" }
$ComputerFilter = $ComputerFilter -join ' -and '
Get-ADComputer -Filter $ComputerFilter
[regex]$Expression = Get-Content $dir\regex.txt

function get_bad_names
{
$result = Get-ADComputer -searchbase $OU 
-Filter {Enabled -eq $true} 
-Properties whenCreated | Where-Object {$_.Name -notmatch $Expression}| sort whenCreated

$result | ConvertTo-Html | Out-File $dir\badnames.html
}

get_bad_names
现在,您可以维护名称模式列表

请记住,-Filter属性不是ActiveDirectory命令上的脚本块。它们都是字符串,尽管有这些命令的文档,它们还是应该这样写。将它们作为脚本块编写最终会导致变量扩展问题

比较:

$ComputerName = hostname
Get-ADComputer -Filter "Name -eq '$ComputerName'"
Get-ADComputer -Filter { Name -eq '$ComputerName' }

谢谢大家的反馈。我对反应如此之快印象深刻

我能够通过从文本文件中读取正则表达式来实现我的目标

我的代码现在如下所示:

$ExcludedPatterns = 'Name1', 'Name2', 'Name3'
$ComputerFilter = foreach ($Pattern in $ExcludedPatterns) { "(Name -notlike '$Pattern')" }
$ComputerFilter = $ComputerFilter -join ' -and '
Get-ADComputer -Filter $ComputerFilter
[regex]$Expression = Get-Content $dir\regex.txt

function get_bad_names
{
$result = Get-ADComputer -searchbase $OU 
-Filter {Enabled -eq $true} 
-Properties whenCreated | Where-Object {$_.Name -notmatch $Expression}| sort whenCreated

$result | ConvertTo-Html | Out-File $dir\badnames.html
}

get_bad_names

您是否需要-notlike运算符,或者简单的-eq检查就足够了?您当前的代码表明平等性检查是可以的。我不确定是否需要-notlike,因为命名约定中有通配符。例如,这些行实际上看起来是这样的:Name-not-like'IT_*.\u*.'为什么不获取所有内容并在事后删除您不想要的内容?你到底想做什么?@Bill\u Stewart,因为-Filter参数将使用提供者的筛选。它比管道输送到物体的位置快一个数量级。我的域名大约有10000台计算机。获取ADComputer-Filter*|其中对象名称-eq$ComputerName大约需要5秒钟。Get-ADComputer-Filter Name-eq'$ComputerName'大约需要9毫秒。@BaconBits是的,我知道您将看到我的许多答案,这些答案正好说明了这一点。这似乎是一个奇怪的要求,我想要更多的信息。事实上,我的建议与Mathias R.Jessen的答案非常相似,它更容易使用-LDAPFilter-IMO。