Использование get ad user для получения разной информации о пользователях домена ad

, I explored techniques for using PowerShell to access data in SQL Server. I covered topics like reading data from a SQL Server table and inserting data into a table. Of course, there are plenty of ways to access SQL Server data without using PowerShell.

Whether you are interested in data analytics or data-driven orchestrations, you will need to know how to  to give PowerShell what it needs. Filtering can be done either at the SQL Server level or within PowerShell itself. However, for handling large datasets, it’s usually best to filter at the SQL level. In this article, I will demonstrate both techniques.

WMI фильтры групповых политики позволяют создать дополнительные условия, в которых определяются параметры компьютеров, к которым нужно нужно применять настройки GPO. Например, с помощью WMI фильтра вы можете применить политику к компьютерам с определенным версией Windows; с определенными настройками; характеристиками оборудования (размеру RAM, HDD); на которых установлена определенная программа; к компьютерам в указанной IP подсети и т.д.

WMI (Windows Management Instrumentation) фильтр в GPO представляет собой запрос на языке WQL (WMI Query Language). Доменный компьютер перед тем, как применить конкретный объект GPO, выполняет такой WMI запрос и опрашивает свое состояние. Если состояние компьютера соответствует условиям выполняются, такая групповая политика будет применена к компьютеру.

In Figure 1, you can see that I have used a simple PowerShell command to read data from a table in a SQL Server database. I added that data to a PowerShell variable named $Data and then outputted the contents by typing the variable name.

Screenshot shows retrieving data from a SQL Server table into a PowerShell variable

PowerShell SQL Filtering 1

I have copied data from a SQL Server table into a PowerShell variable.

Since we now have this data in a PowerShell variable, we can apply all the usual techniques to access the specific data we need.

In the figure above, the quantity of items sold in July is 35. Let’s suppose that, for whatever reason, we need to isolate this quantity so that we can take action on it.

To do so, we could use a command like this:

Although this command returns both the month (July) and the quantity of items sold (35), our goal is to isolate just the quantity. One way to accomplish this is to map the command to another variable, which I will name $RawData. By doing this, we can access the desired data by calling $RawData.ItemsSold. An example can be seen in Figure 2.

Screenshot shows the referencing a single data point from a SQL Server database

PowerShell SQL Filtering 2

I have referenced a single data point from a SQL Server database.

Notice that I had to change the operator from -eq to -like. You can see what this looks like in Figure 3.

Screenshot shows modifying filtering criteria in PowerShell

PowerShell SQL Filtering 3

You can filter the data based on any criteria that you choose.

powershell where-object

If you’ve ever found yourself needing to filter data in PowerShell, then you’ve likely encountered the powerful Where-Object cmdlet. This versatile cmdlet, often just called Where, allows you to filter objects based on their properties. You can use this cmdlet to filter out objects based on specified conditions, enabling you to quickly narrow down your results and focus on the relevant information.

The Where-Object cmdlet is a versatile and flexible tool in PowerShell, allowing you to filter data using various techniques. This article will provide an in-depth analysis of these techniques and show you how to use them effectively to enhance your PowerShell skills. We will cover the basic syntax and usage of Where-Object, advanced filtering with multiple conditions, using comparison operators, implementing wildcards and regular expressions, and combining techniques for precise results.

In this guide, you’ll learn:

  • What is Where-Object, and why is it useful?
  • Filtering collections with simple property comparisons
  • Using operators like -eq, -ne, -gt, -lt etc.
  • Leveraging -like and -notlike for wildcard filtering
  • Using the -is and -isnot operators to check the type of an object.
  • Matching on regular expressions with -match and -notmatch
  • Combining multiple filters with -and and -or
  • Filtering based on object types, dates, times, and more
  • Case-sensitive filtering with -ccontains and -cmatch
  • Filtering nested properties and calculated values

Two of the most commonly used filtering techniques in PowerShell are Where-Object, and the filter keyword in function definitions. In this PowerShell tutorial, I will explain everything about the PowerShell Where-Object vs Filter.

In PowerShell, Where-Object is a cmdlet used for filtering objects based on specified criteria within a pipeline, allowing for complex expressions. On the other hand, the filter keyword defines a function that acts as a dedicated filter, which can be more efficient for repeated use. Where-Object is more versatile for inline, ad-hoc filtering, while filter is better for scenarios where a specific, reusable filter is beneficial.

Example of Where-Object

Get-Process | Where-Object { $_.CPU -gt 100 }

This command retrieves all processes with a CPU usage greater than 100. The $_ represents each object that comes through the pipeline, which in this case is each process.

PowerShell Filter in Function Definitions

The filter keyword in PowerShell is used to define a function that inherently acts as a filter. Functions defined using filter are designed to process input from the pipeline just like Where-Object, but they are generally more concise and can be more efficient in certain scenarios.

Example of Filter

filter HighCPUUsage { if ($_.CPU -gt 100) { $_ } }
Get-Process | HighCPUUsage

This defines a filter function named HighCPUUsage that filters processes with CPU usage greater than 100, similar to the Where-Object example.

Comparing Where-Object and Filter in PowerShell

While both Where-Object and filter serve similar purposes, they have differences in syntax, performance, and use cases. Let’s explore these differences in detail.

Differences in Syntax

Differences in Performance

Differences in Use Cases

Where-Object is versatile and can be used for one-off, complex filtering directly within a pipeline. filter functions are better suited for scenarios where the same filtering logic needs to be reused across multiple scripts or sessions.

PowerShell Where-Object vs Filter

Here are the complete differences of PowerShell Where-Object vs Filter.

FeatureWhere-ObjectFilter Function
DefinitionCmdletKeyword to define a function
SyntaxInline script block or comparison statementNamed function that can be reused
PerformanceCan be slower due to runtime interpretationGenerally faster due to compilation
ReusabilityOne-off use in pipelinesCan be reused across scripts and sessions
ComplexitySupports complex logicBest used for simpler, more focused filtering logic
VersatilityHighly versatile, can be used with any cmdletLimited to the defined function, not universally applicable
Pipeline Input ProcessingProcesses each object in the pipelineProcesses each object in the pipeline
CustomizabilityHighly customizable with script blocksCustomizable within the function definition
Ease of UseSimple for quick, one-time filters but can get complex for advanced filteringSimple and clean for defining reusable filters, but requires understanding of function definitions

Example of PowerShell Where-Object vs Filter

Now, let us understand with an example of where to use the PowerShell Where-Object Vs Filter.

Suppose you want to filter event logs for events with an ID of 1000.

Using Where-Object

Get-EventLog -LogName Application | Where-Object { $_.EventID -eq 1000 }

This command retrieves all application event logs with an EventID of 1000.

Using Filter

filter EventIDFilter { if ($_.EventID -eq 1000) { $_ } }
Get-EventLog -LogName Application | EventIDFilter

This defines a filter function EventIDFilter that you can use to retrieve the same event logs.

PowerShell Where-Object vs Filter

Conclusion

Both Where-Object and filter are very useful cmdlets in PowerShell. Where-Object is flexible and powerful for inline filtering, while filter functions provide a clean and potentially more performant way to apply filters, especially when the same logic is needed repeatedly.

:/>  Как на жёстком диске убрать все разделы, если некоторые из них защищены от удаления | Белые окошки

I hope now you understand whether you choose Where-Object or filter, both while managing and manipulating data within PowerShell. Leave your thoughts on PowerShell Where-Object vs Filter in the comments.

You may also like:

Не секрет, что начиная с первой версии PowerShell, Microsoft пытается сделать из него основной инструмент администрирования Windows. И во многом это получается! Сегодня на простых примерах, мы покажем возможности PowerShell, которые можно использовать для получения различной информации о пользователях Active Directory и их атрибутах.

Примечание. Ранее для получения информации об атрибутах учетных записей пользователей AD приходилось использовать различные инструменты: консоль ADUC (в том числе сохраненные запросы AD), vbs скрипты, утилиту dsquery и т.п. Выбор инструмента обычно основывался на поставленной задачи и способностях администратора в программировании.

Запускаем окно Powershll с правами администратора и импортируем модуль Active Directory командой:

Import-Module activedirectory

Совет. В Windows Server 2012 и выше этот пункт можно пропустить, так как модуль PowerShell Active Directory подключен по-умолчанию.

RSAT включить модуль Active Directory Module for Windows PowerShell

help Get-ADUser

Чтобы вывести список всех учетных записей домена, выполним команду:

Get-ADUser -filter *

Важно. Не рекомендуется выполнять эту команду в доменах с большим количеством аккаунтов, т.к. возможно перегрузка контроллера домена, предоставляющего данные.

Get-ADUser -filter * - вывести список всех пользователей в ADФормат возвращаемого списка не очень удобен для использования, выводится только некоторые основные 10 из более 120 атрибутов и свойств учетных записей пользователей (DN, SamAccountName, Name, SID, UPN и т.д) кроме того, мы видим, что информация о времени последней смены пароля отсутствует.

Get-ADUser -identity tuser -properties *
  • PasswordExpired
  • PasswordLastSet
  • PasswordNeverExpires
Get-ADUser tuser -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires

Get-ADUse - время смены и истечения срока действия пароля в ADТеперь в данных пользователя есть информация о дате смены пароля и времени, когда срок пароля истечет. Представим информацию в более удобном табличном виде:

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires

Get-ADUser - табличное преставление о свойствах пользователейЧтобы вывести данные пользователей из определенной OU, воспользуемся параметром SearchBase:

Get-ADUser -SearchBase ‘OU=Moscow,DC=winitpro,DC=loc’ -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires

Результат выполнения команды можно выгрузить в текстовый файл:

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires > C:\temp\users.txt

Или в CSV, который в дальнейшем будет удобно экспортировать в Excel (дополнительно с помощью sort-object отсортируем таблицу по столбцу PasswordLastSet , а также добавим условие where – имя пользователя должно содержать строку «Dmitry»):

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | where {$_.name –like “*Dmitry*”} | sort-object PasswordLastSet | select-object Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires | Export-csv -path c:\temp\user-password-expires-2015.csv

Get-ADUser с условием where и сохранением в csv

Таким образом, можно построить таблицу с любыми необходимыми атрибутами пользователей Active Directory.

Совет.  Для получения данных о компьютерах Active Directory используется командлет Get-ADComputer.

Далее приведем еще несколько полезных вариантов запросов о пользователях Active Directory с помощью различных фильтров. Вы можете их комбинировать для получения необходимого списка пользователей AD:

Вывод пользователей AD, имя которых начинается с Roman:

Get-ADUser -filter {name -like "Roman*"}

Чтобы подсчитать общее количество всех аккаунтов в Active Directory:

Get-ADUser -Filter {SamAccountName -like "*"} | Measure-Object

Список всех активных (не заблокированных) учетных записей в AD:

Get-ADUser -Filter {Enabled -eq "True"} | Select-Object SamAccountName,Name,Surname,GivenName | Format-Table

Список учетных записей с истекшим сроком действия пароля:

Get-ADUser -filter {Enabled -eq $True} -properties passwordExpired | where {$_.PasswordExpired}

Список активных учеток с почтовыми адресами:

Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Format-Table

Задача: для списка учетных записей, которые хранятся в текстовом файле (по одной учетке в строке) нужно получить телефон пользователя в AD и выгрузить информацию в текстовый csv файл (можно легко импортировать в Esxel).

Import-Csv c:\ps\usernsme_list.csv | ForEach {
Get-ADUser -identity $_.user -Properties Name, telephoneNumber |
Select Name, telephoneNumber |
Export-CSV c:\ps\export_ad_list.csv -Append -Encoding UTF8
}

Следующий пример позволяет выгрузить адресную книгу предприятия в виде csv файла, который в дальнейшем можно импортировать в Outlook или Mozilla Thunderbird:

Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Export-Csv -NoTypeInformation -Encoding utf8 -delimiter "," $env:temp\mail_list.csv

Пользователи, которые не меняли свой пароль в течении последних 90 дней:

$90_Days = (Get-Date).adddays(-90)
Get-ADUser -filter {(passwordlastset -le $90_days)}

Чтобы получить фотографию пользователя из Active Directory и сохранить ее в jpg файл:

$user = Get-ADUser winadmin -Properties thumbnailPhoto
$user.thumbnailPhoto | Set-Content winadmin.jpg -Encoding byte

Список групп, в которых состоит учетная запись пользователя

Get-AdUser winadmin -Properties memberof | Select memberof -expandproperty memberof

Using the Where-Object command with PSObject in PowerShell

Let’s walk through a simple real-world scenario using Where-Object with PSCustomObject in PowerShell. Say you have a list of employees. You want to find all employees who earn more than a specific threshold.

# Creating a list of employees as PSCustomObjects
$Employees = @( [PSCustomObject]@{Name="Alice"; Position="Developer"; Salary=75000}, [PSCustomObject]@{Name="Bob"; Position="Designer"; Salary=60000}, [PSCustomObject]@{Name="Charlie"; Position="Manager"; Salary=85000}, [PSCustomObject]@{Name="David"; Position="Developer"; Salary=68000}
)
# Filtering employees with a salary greater than 65000
$HighEarners = $Employees | Where-Object { $_.Salary -gt 65000 }
# Displaying the high earners
$HighEarners | Format-Table -Property Name, Position, Salary
filter objects in powershell using where-object

Как создать и привязать WMI фильтр к GPO

Для управления WMI фильтрами используется консоль управления доменными групповыми политиками .

  1. Откройте консоль
    gpmc.msc
  2. Перейдите в раздел WMI Filters и создайте новый фильтр
  3. Укажите название фильтра и описание (не обязательно)Создать WMI фильтр групповых политик
  4. Нажмите Add. Выберите пространство имен WMI (в большинстве случаев используется root\CIMv2). Укажите код WMI запроса в следующем формате:
    Select * from <WMI Class> WHERE <Property> = <Value>
    Например, следующий WMI запрос можно использовать, чтобы применить GPO только к компьютерам с Windows 10 и 11:
    Select * from Win32_OperatingSystem where Version like "10.%" and ProductType="1"

    Указать код wmi запроса в фильтре gpo
  5. Теперь WMI фильтр можно привязать к GPO. Например, вы хотите, чтоб политика установки принтеров применялась только к компьютерам с Windows 10 и 11. В разделе WMI Filtering групповой политики выберите WMI фильтр, который вы создали.Привязать WMI фильтр к политике домена
  6. Обновите настройки GPO на клиентах. Теперь политика будет применяться только к компьютерам, которые удовлетворяют условиям WMI фильтра. Для анализа примененных политики можно использовать команду gpresult /r. Если политика действует на клиента, но не применяется из-за WMI фильтра, такая политика в отчете gpresult будет иметь статус
    Filtering: Denied (WMI Filter)
    и указано имя WMI фильтра.gpresult фильтрация по wmi запросам

Using PowerShell Where Command with the Property Parameter

Get-Service | Where-Object -Property StartType -Eq -Value Disabled

In the above example, we are filtering the services based on their StartType property using the property parameter. Only the services with a StartType of ‘Disabled’ will be selected.

Here is another example of filtering based on the property value of an object:

Get-ChildItem C:\Temp -File | Where Length -gt 1MB
powershell where

Let’s find all files with .txt extension using PowerShell:

Get-ChildItem -Path C:\Docs | Where-Object { $_.Extension -eq ".txt" }

Filtering Objects based on their types with IS and ISNOT operators

in PowerShell, the -is and -isnot operators are used to check the type of object. Here are quick examples demonstrating how to use these operators with the Where-Object cmdlet, which is often abbreviated as Where.

# Create an array with different types of objects
$items = 42, "hello", 64, [DateTime]::Now, 100
# Use the -is operator to filter out only integers
$items | Where-Object { $_ -is [int] }

Similarly, use the -isnot operator to filter out everything that is not a specific type (E.g., string)

$items | Where-Object { $_ -isnot [string] }

Troubleshooting common errors in PowerShell filtering

When working with PowerShell filters, you may encounter some common errors. Here are some tips for troubleshooting these errors:

  1. Incorrect use of comparison operators: Ensure you are using the correct comparison operator for your filter condition. For example, use -eq for equality and -gt for greater than.
  2. Syntax errors in script blocks: Make sure your script block statement is enclosed in curly braces ({}) and that your conditions are properly formed.
  3. Incorrect property names: Ensure you are using the correct property names for the objects you are filtering. You can use the Get-Member cmdlet to view the properties of an object.
:/>  Сочетания клавиш вставить как текст и как вставить только текст без форматирования в Microsoft Word из любой другой программы

Filtering Nested Properties

You can filter on nested object properties using dot notation. You can also chain properties:

Get-ADUser -Filter * | Where-Object {$_.Enabled -and $_.Manager.Name -like "*Smith"}

Here is another example of filtering Windows Event Log by EventID:

# Fetching application log events with EventID 1001
$Events = Get-EventLog -LogName Application | Where-Object { $_.EventID -eq 1001 }
# Displaying the first 5 results
$Events | Select-Object -First 5

Filtering with multiple conditions in Script Block

You can use the Where-Object PowerShell cmdlet to filter results based on multiple conditions. To do this, you can use logical operators such as -and, -or, and -not to combine your conditions. Here is an example of using multiple conditions to filter the results of the Get-Process cmdlet:

Get-Process | Where-Object {$_.WorkingSet -gt 10MB -and $_.CPU -gt 300}

In this example, we are filtering the results to display only processes with a working set greater than 10MB and a CPU time greater than 300 seconds. The -gt operator is a comparison operator that checks if the specified property is greater than the given value.

Get-Service | Where-Object -FilterScript {$_.Status -eq 'Stopped' -and $_.StartType -eq 'manual'}

How to Filter with Regular Expressions in PowerShell?

Regular expressions can be used in Windows PowerShell by using the -match, -notmatch, -replace, and other similar operators. Let’s learn how to filter using these operators within the Where-Object cmdlet, and apply filter data based on a pattern match or wildcard characters. E.g.,

Get-Process | Where-Object {$_.Name -match "^S.*"} | Select Name, ID

Here, we use a regular expression and a match operator to filter input objects (processes in this case) based on their names. The script selects only the processes whose names start with the letter ‘S’.

Проверка WMI фильтров с помощью PowerShell

WMI фильтры перед применением в GPO можно протестировать на целевых компьютерах. Это позволит понять, будет или не будет политика с таким WMI запросов применяться на определенных компьютерах. Для просмотра всех доступных WMI классов на компьютере выполните PowerShell команду:

Вывести доступные атрибуты и значения WMI класса Win32_OperatingSystem:

Get-WMIObject просмотр объектов и значений wmi классов

Чтобы проверить ваш WMI запроса на компьютере и понять, соответствует ли компьютер данному запросу или нет, укажите его код в параметре -query. Например, такой WMI запрос проверяет, установлен ли на компьютере Microsoft Office:

Get-WmiObject -query 'Select * From Win32_Product where Name like "%Office 16 Click-to-Run%"'

Если такая команда возвращает в ответ список атрибутов, значит компьютер соотвествует вашему запросу и GPO с таким WMI фильтром будет применена. Если команда get-wmiobject ничего не вернула — компьютер не соответствует запросу.

Проверка рузультатов WMI запроса с помощью PowerShell

В новых версиях PowerShell Core 7.x, командлет Get-WmiObject является устаревшим и вместо него нужно использовать
Get-CimInstance
.

WMI фильтры GPO позволяют создать динамические правила, в которых определяются характеристики компьютеров, к которым нужно применить групповые политики.

Filtering Calculated Values

Where-Object filters don’t have to be static values. You can perform calculations. Let’s use PowerShell to find all the files in a specific directory that were created within the past 30 days:

Get-ChildItem -Path C:\Temp -File |
Where-Object { $_.CreationTime -gt (Get-Date).AddDays(-30) } |
Select-Object Name, CreationTime

In this script, We calculate the threshold date, which is 30 days from the current date, and then filter the results with Where-Object based on the CreationTime property.

Using comparison operators in the Where-Object filter

PowerShell uses several comparison operators that you can use for filtering data, including equality operators, matching operators, Containment Operators, etc.

OperatorDescription
Eq / NeEqual to / Not equal to
Gt / GeGreater than / Greater than or equal to
Lt / LeLess than / Less than or equal to
Like / NotLikeMatches a pattern using wildcards / Does not match a pattern using wildcard characters
Match / NotMatchString matches regex pattern / Does not match a pattern using regular expressions
Contains / NotContainsContains a substring / Does not contain a substring
In / NotInUsed to check whether a specified value exists in a set of values / Not exists in the set of values
Ceq / Cne / Cmatch / CNotMatch / Clike / CNotLike / CContains / Cin/CnotinCase-sensitive equal to/not-equal to/match/Notmatch/like/Not-like/contains/in/Not-in
Cge / Cgt/ Clt / CleCase-sensitive greater than or equal to, Greater than, Less than, Less than or equal to

These operators allow you to create complex filtering conditions for your Where-Object cmdlet, giving you greater control over the data you work with in PowerShell. More on Comparison Operators in PowerShell is here! PowerShell Comparison Operators: An Essential Guide

Here is a simple example with Get-Service cmdlet, which returns a list of computer services. With the PowerShell where-object cmdlet, we can filter the list to return only services that have a specific property, such as:

Get-Service | Where-Object { $_.Status -eq "Running" }

In this example, we filtered the list to return all services in the “Running” state. The $_.status property checks whether a service is running or stopped, and we used the -eq (equals) operator to return only those services that have the status property set to “Running”.

How to use the PowerShell Where-Object cmdlet for Wildcard Filtering?

To enable wildcard searches, use the PowerShell operators -like and -notlike.

Get-Command | Where-Object { $_.Verb -Like "Get*" }
$Names = "Alex", "Jane", "Andrew", "Emily"
$FilteredNames = $Names | Where-Object { $_ -like "A*"}

The below example filter processes that contain “Chrome” in their name:

Get-Process | where {$_.Name -contains "Chrome"} 

Filtering with Multiple comparison operators

Get-ChildItem -Path 'C:\Temp' -Include '*.jpg', '*.mov' -Recurse | Where-Object {$_.Length -gt 10MB -and $_.LastWriteTime -gt (Get-Date).AddDays(-10)}

This command recursively searches the C:\ drive for .jpg and .mov files and filters them based on size and modification date. Here is another example of using a where clause with date values:

Get-ChildItem | Where-Object {$_.CreationTime -gt [datetime]"01/01/2022"}

SQL Server Filtering

The filtering techniques that I have demonstrated so far work well when dealing with small datasets. However, what if you need to interact with a table containing millions of rows? Depending on the volume of data, it may exceed PowerShell’s capacity. Even if PowerShell handles such volumes, filtering the data could strain your system. As such, it is often more practical to let SQL Server handle the filtering task.

Countless techniques exist for filtering SQL Server data. In fact, entire books have been written on the subject. Even so, I want to illustrate how we can perform some basic SQL Server filtering by simply modifying our query.

$Data=Invoke-SQLCmd -ServerInstance Win11SQLSQLEXPRESS -Database MyAppDB -Query “Select Month, ItemsSold From Table1”

In this command, the Query portion specifies the data to retrieve. Therefore, if we want to give PowerShell a smaller dataset to work with, we can simply modify the Query statement to include a filter. This can be done using a Where statement

Suppose that I want to repeat the earlier task of isolating the number 35, which represents the items sold in July. On the surface, it seems that the query statement should be something like this: Select ItemsSold From Table1 Where  Month = ‘July’. However, things aren’t quite so simple.

There are two problems with the above Select statement. The first problem is that the Where statement uses the Month column as a filter. Even though we are only interested in returning the ItemsSold data, we must include the Month column in the Select portion of the statement (as opposed to only including the ItemsSold column). Otherwise, SQL can’t filter the data based on the month.

:/>  Управление и восстановление жесткого диска, карты памяти или USB-флешки

The other problem with the statement is that, as you may recall from my original article, the Month column in the table is a text data type. If you try to perform a comparison operation on a text column, you will receive an error message stating, “The data types text and varchar are incompatible in the equal to operator.” In other words, the filter (July) is being treated as VARCHAR data, while the data in the table’s Month column is text data, and you can’t compare the two.

To resolve this problem, we can convert the text data into VARCHAR data. Thankfully, this is easy to do and doesn’t require any modifications to the database table. We only need to add a convert command to the Select statement.

Hence the final Query statement is:

Select Month, ItemsSold From Table1 Where Convert(VARCHAR,Month) = ‘July’;

In Figure 4, you can see the original command that produced the error and the correct command. As shown, accessing the number 35 is simply a matter of typing $Data.ItemsSold.

Screenshot shows filtering data within the SQL Select statement

PowerShell SQL Filtering 4

This is how you filter the data within the SQL Select statement.

Select Month, ItemsSold From Table1 Where Convert(VARCHAR,Month Like ‘J%’;

You can see the full command in Figure 5.

Screenshot shows SQL Server filtering results for months starting with J

PowerShell SQL Filtering 5

SQL Server has filtered the results to only include months beginning with the letter J.

Best Practices for Efficient Filtering

  1. Filter as early as possible in the command to limit the number of results passed through the pipeline.
  2. Utilize filterable parameters provided by cmdlets whenever possible.
  3. Use specific properties to filter objects effectively.
  4. Take advantage of comparison operators and regular expressions for flexible filtering.
  5. Use aliases like ‘Where’ for brevity and easier readability.
  6. Combine filters using logical operators such as -and, -or, -xor to create more complex conditions.
  7. Minimize the use of the pipeline: Each time you use the pipeline, PowerShell has to do a bit of extra work, marshaling the objects and unmarshaling them on the other end
  8. Use -Filter parameter When available: Use cmdlets with the -Filter parameter instead of Where-Object. This will do the filtering right at the source, which can dramatically improve performance. E.g., Get-ADUser

Understanding Where-Object Filtering Techniques in PowerShell

Basic PowerShell Where-Object syntax and usage

Get-Command | Where-Object {<filter script>}
<Command-That-Produces-Output> | Where-Object { $_.<PropertyName> -<Operator> <Value> }
PowerShell Where cmdlet

Let’s go through a simple example where we have a list of numbers, and we want to filter out only the even numbers using Where-Object in PowerShell.

$Numbers = 1..100
$EvenNumbers = $Numbers | Where-Object { $_ % 2 -eq 0 }

In the above example, We have first created a range of numbers from 1 to 100 using $numbers = 1..100. We then filter the even numbers by piping the $numbers array into Where-Object. The condition $_ % 2 -eq 0 checks if a number is even. ($_ represents the current number being processed in the pipeline.)

Get-Service | Where-Object {$_.Status -eq 'Running'}

In this example, the $_ automatic variable represents the current object in the pipeline. We have used the comparison statement -eq that checks if the Status property of the current object is equal to 'Running'. If it is, the object is included in the output. In short, the where condition used in this PowerShell filters the output.

PowerShell Where-Object

PowerShell also provides shorthand aliases and syntax for some of these cmdlets. For Where-Object, you can use ? as an alias:

Get-Service | ? { $_.Status -eq "Running" }

This example returns objects that satisfy the particular property value. In this case, filter services with running status.

Примеры WMI запросов для фильтров GPO

Рассмотрим часто используемые примеры WMI запросов для фильтров GPO.

В зависимости от типа ОС:

  • ProductType=1 – рабочая станция (клиентская версия Windows)
  • ProductType=2 – контроллер домена AD
  • ProductType=3 – серверная ОС (Windows Server)

В зависимости от версии Windows:

Version like "X.X%"

  • Windows Server 2016/2019/2022 и Windows 10/11 — 10.%
  • Windows Server 2012 R2 и Windows 8.1 — 6.3%
  • Windows Server 2012 и Windows 8 — 6.2%
  • Windows Server 2008 R2 и Windows 7 — 6.1%
  • Windows Server 2008 и Windows Vista — 6.0%
  • Windows Server 2003 — 5.2%
  • Windows XP — 5.1%

С помощью логических операторов AND и OR можно комбинировать несколько условий в WMI запросе. Например, чтобы применить GPO только к серверам с Windows Server 2019:

select * from Win32_OperatingSystem WHERE Caption LIKE "%2019%" AND Version LIKE "10.%" AND ( ProductType = "2" or ProductType = "3")

Компьютеры с 64 битными версиями Windows 10:

select * from Win32_OperatingSystem WHERE Version like "10.%" AND ProductType="1" AND OSArchitecture = "64-bit"

Компьютеры с определенным билдом Windows 11 (например, 23H2, билд 22631):

select * from Win32_OperatingSystem WHERE Caption like "%Windows 11%" AND ProductType="1" AND BuildNumber = "22631"

Применить политику только к виртуальным машинам VMWare:

SELECT Model FROM Win32_ComputerSystem WHERE Model LIKE "%VMware%"

Применить политику только к ноутбукам:

select * from Win32_ComputerSystem where PCSystemType="2"

Только к десктопным компьютерам (рабочим станциям):

select * from Win32_ComputerSystem where PCSystemType="1" or PCSystemType="3"

WMI фильтр для выбора компьютеров, чьи имена начинаются на “msk-pc

SELECT Name FROM Win32_ComputerSystem WHERE Name LIKE "msk-pc%"

Применить политику только к компьютерам в определенных IP подсетях (WMI фильтр для привязки GPO к IP подсети):

Select * FROM Win32_IP4RouteTable WHERE (Mask='255.255.255.255' AND (Destination Like '192.168.1.%' OR Destination Like '192.168.2.%'))

Компьютеры с более чем 4 ГБ RAM:

Select * from WIN32_ComputerSystem where TotalPhysicalMemory >= 4200000000

Компьютеры, на которых установлен архиватор 7ZIP:

Select * From Win32_Product where Name like "%7-Zip %"

На которых установлен Internet Explorer (по умолчанию IE удален в современных версиях Windows):

SELECT path,filename,extension,version FROM CIM_DataFile WHERE path="\\Program Files\\Internet Explorer\\" AND filename="iexplore" AND extension="exe" AND version>"11.0"

Case-Sensitive Matching in Where Object Command

By default, the PowerShell where object command filtering is not case-sensitive. Use -cmatch and -ccontains for case-sensitive comparisons:

"John","Sarah","JAKE","john" | Where-Object {$_ -ccontains "john"}

This will match the string “john” from the given array. For case-sensitive regular expressions, use:

Get-service | Where-Object {$_.Name -cmatch "^[a-z]"}

Now, only names starting with a lowercase letter will match.

Conclusion

In conclusion, you can use the Where-Object script in PowerShell to find the items you need with great accuracy. It lets you filter results to find specific elements rather than showing everything in a list. By learning the syntax, comparison operators, and advanced filtering techniques, you can get the exact information you want.

Whether you are working with files, services, or processes, the Where-Object cmdlet is your best tool for filtering data in PowerShell. Remember, practice makes perfect. Try different filtering examples, learn advanced options, use best practices, and become good at using the Where-Object cmdlet. Happy scripting!

What is Where-Object In PowerShell?

Where-Object is a cmdlet in PowerShell that allows you to filter objects from a collection based on specific criteria. It is used to select objects that meet certain conditions and discard the rest. This cmdlet is commonly used in PowerShell scripts and commands to manipulate and filter data.

Can I use Where-Object with other cmdlets?

Yes, you can use Where-Object with other cmdlets to selectively filter and process objects in the PowerShell Pipeline. You can combine this versatile cmdlet with various others to accomplish specific tasks.

How can I negate a filtering condition in Where-Object?

Can I use Where-Object to filter arrays or collections?

Yes, you can use Where-Object to filter arrays or collections of objects. You can pipe an array or collection to Where-Object and specify the filtering conditions based on the properties of the objects in the array or collection.

How do I remove duplicates from an object in PowerShell?

What is the alias for where-object in PowerShell?

How do I find the property of an object in PowerShell?

How to check object type in PowerShell?

How to use the PowerShell where-object is not null?

How do I use multiple conditions in Where-Object

PowerShell Select-Object and Where-Object

Sometimes, you may want to filter a dataset and then select specific properties of the filtered objects to display. To achieve this, you can use the Select-Object cmdlet in combination with the Where-Object cmdlet in PowerShell scripts.

Here is an example of how to use PowerShell Where-Object and Select-Object cmdlets to retrieve a list of running services and display their name and status:

Get-Service | Where-Object {$_.Status -eq 'Running'} | Select-Object Name, Status

In this example, the first command Get-Service retrieves a list of services, which is then filtered by the second command Where-Object to display only running services. Finally, the Select-Object cmdlet is then used to select the Name and Status properties of the filtered objects.

About the Author(s)

Brien Posey

Brien Posey is a bestselling technology author, a speaker, and a 20X Microsoft MVP. In addition to his ongoing work in IT, Posey has spent the last several years training as a commercial astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space.