使用该-Filter
参数来执行此操作,尽管我们需要做一些工作才能以适合的格式获取日期whenCreated
,因为它在 AD 架构中的定义与其他一些“日期”类型属性不同。下面的代码将起作用,解释如下:
注意:-Properties *
我在下面简要提到它,但如果你能帮助它,你不想这样做。返回对象的所有静态属性可能会导致您所击中的 DC 上的负载过大。仅指定要返回的属性。有关更详细的说明,请参阅此答案底部的链接答案。
# Create a yyyMMddHHmmss.Z formatted date string in UTC
$SomeDate1= ( Get-Date 'Wednesday, November 7, 2018 2:41:59 PM' ).ToUniversalTime().ToString('yyyMMddHHmmss.Z')
# These are the properties we both want to return from AD and include in the final output
$propertiesToReturn =
"Name",
"OperatingSystem",
"OperatingSystemVersion",
"ipv4Address",
"Created",
"whenCreated",
"Deleted",
"whenChanged",
"Modified",
"Description",
"DisplayName",
"Location",
"DistinguishedName",
"DNSHostName"
# These are properties we need from AD but are not required directly in the final output
$additionalProperties =
"CanonicalName",
"ServicePrincipalNames"
# Define the computed property here for clarity
$spnComputedProperty = @{
Label = "ServicePrincipalNames";
Expression = {
$_.ServicePrincipalNames -join ";"
}
}
# Obtain the target computer list and apply your select-object expression to it
Get-ADComputer -Filter "whenCreated -gt '${SomeDate1}'" -Properties ( $propertiesToReturn + $additionalProperties ) | Where-Object {
$_.CanonicalName -match 'Unix'
} | Select-Object ( $propertiesToReturn + $spnComputedProperty )
现在,这里有很多变化,所以我将解释我做了什么以及为什么:
新变量和对现有变量的更改
- 我省略
$SomeDate2
了,因为在您的代码示例中没有以其他方式引用它。
$SomeDate1
Interval
与其他日期类型属性(例如LastLogonDate
. 相反,它被定义为格式中的通用时间字符串yyyMMddHHmmss.Z
并且采用 UTC,因此我们需要以这种方式格式化的时间戳,而不是依赖于ToString()
a 的默认行为[DateTime]
。如果我们不这样做,日期比较将不起作用。这是令人困惑的,因为 RSAT AD Cmdlet会将此(和其他通用时间字符串)转换为本地化DateTime
字符串,以便在最终返回数据时更轻松地进行 PowerShell 处理。
- 请注意,
yyyMMddHHmmss.Z
不能直接转换回DateTime
对象以在其他地方使用。
- 为清楚起见,我定义了从数组返回的通用属性,
Get-ADComputer
并
Select-Object
定义了另一个数组,其中包含我们只想从 AD 返回以进行进一步处理的元素。它们分别是$propertiesToReturn
和$additionalProperties
。这使我们不必在多个地方重新定义这些属性,并允许我们避免代价高昂的
-Properties *
调用。
ServicePrincipalNames
包含在下面$additionalProperties
是因为你想将属性值转换为字符串,所以我们不想将它的原始值包含在Select-Object
.
CanonicalName
是计算属性,不能在-Filter
或中过滤
-LDAPFilter
。我们必须在本地返回并处理此属性,即使您不希望它出现在最终输出中。
- 无论如何都会返回一些定义在下面的属性名称,但将它们包含在数组
$propertiesToReturn
中并没有什么坏处。-Properties
- 同样为清楚起见,我已将您的计算属性定义
Select-Object
为$spnComputedProperty
变量。这可以在单行上,但为了便于阅读,我在这里将其设置为多行。
Get-ADComputer
用适当的调用-Filter
现在我们的属性数组和日期字符串格式正确,我们终于可以调用
Get-ADComputer
.
- 我们可以使用
"whenCreated -gt '${SomeDate1}'"
过滤字符串(不要使用with ScriptBlock
)-Filter
来返回所有ADComputers
在 之后创建的$SomeDate1
。
- 通常我不建议使用连接字符串或数组,
+
但这是一个方便的例外,不太可能导致内存问题。因为Get-ADComputer -Properties
我们提供$propertiesToReturn
和$additionalProperties
作为一个单一的阵列。
- 尝试使用该语法
-Properties $propertiesToReturn, $additionalProperties
将导致类型不匹配错误。
- 我已将您的
Where-Object
子句缩减为仅进一步过滤CanonicalName
. 如上所述,CanonicalName
是一个计算属性,不能用
-Filter
or过滤-LDAPFilter
,必须在此处完成。
- 我还更改
-like
并-match
从*
(技术上的正则表达式)表达式中删除了,但-like
如果您愿意,可以将原始子句与 glob 一起使用。
Select-Object
最后,我们像之前一样将结果通过管道传输到,并执行与 . 相同的连接技巧Get-ADComputer -Properties
。但是,这次我们添加$spnComputedProperty
了。
这应该会为您提供所有在您希望的属性中指定的日期之后创建的内容,包括自定义ADComputers
字段。$SomeDate1
Unix
CanonicalName
ServicePrincipalNames
关于避免将目标转换DateTime
为广义时间格式的注意事项
从技术上讲,您可以使用以下任一过滤器来避免需要将您转换DateTime
为使用通用时间格式:
Get-ADComputer -Filter 'whenCreated -lt $SomeDate1'
# Double-quoted variant is useful if you have other variables which
# should be directly rendered as part of the -Filter string
Get-ADComputer -Filter "whenCreated -lt `$SomeDate1"
我避免提及这一点的原因是因为这种行为没有得到很好的理解或记录。cmdlet 有一些魔法来获取变量值,即使它不应该被呈现,因为它是一个文字字符串。由于人们对它了解甚少,并且不清楚什么规则集定义了如何DateTime
转换(例如,每个属性和类型的规则是否发生变化,是否DateTimes
总是转换为通用时间字符串?我们不知道)我不推荐这种方法.
的行为whenCreated
在 AD Schema 文档中得到了很好的记录,如果我从一开始就查阅了这些内容,就会很清楚-Filter
需要如何制作,而不是为了理解比较问题而进行的反复试验。文档链接如下。
其他资源
如果您对未正确过滤的 AD 属性有奇怪的行为,或者您只是想了解更多关于不同属性的信息,我建议您在OpenSpecs或AD Schema文档中查找该属性。
另外,请参阅我的这个答案,其中详细介绍-Filter
了 RSAT AD cmdlet 上的参数。