Сбор информации о рабочих станциях через Powershell / Хабр

Как в PowerShell фильтровать вывод командлета

Where-Object – фильтр. Сводим результаты PowerShell к самому необходимому

В предыдущих статьях рубрики я рассказывал о том, как с помощью конвейера (|), объединяющего несколько команд PowerShell в цепочку, можно создавать простые отчеты, например:

get-aduser –f * -pr lastlogondate | select samaccountname,lastlogondate | sort lastlogondate

Эта комбинация команд позволяет вывести список имен пользователей, выбрать только имена и даты последней регистрации и отсортировать результаты по дате последней регистрации. Результат выполнения такого запроса может содержать много ненужной информации. Предположим, нам требуется вывести имена и даты последней регистрации не всех пользователей, а только тех, кто не заходил в систему в течение определенного времени.

Эту задачу позволяет решить команда where-object, которую практически никогда не вызывают по полному имени. В большинстве случаев для ее вызова используется where или знак вопроса (?). В предыдущих публикациях речь шла о парах команд PowerShell, состоящих из команды вывода учетных записей, соответствующих определенному критерию и команды-действия (применение определенного действия к извлеченному подмножеству AD). Рассматривались и некоторые команды, содержащие фильтры: get-aduser, search-adaccount и другие.

Where-object – это фильтр. Чтобы понять синтаксис команды, начнем с примера. Для вывода пользователей, не запускавших систему после 1 января 2013 года, построим следующий запрос:

get-aduser -f * | where {$_.lastlogondate -le «1 January 2013»}

Команда get-aduser извлекает все учетные записи пользователей домена. Результаты передаются по конвейеру команде where-object, которая проверяет каждый входящий объект на соответствие определенному критерию. Критерий, заключенный в фигурные скобки, заслуживает отдельного рассмотрения.

Запись –le означает «меньше или равно»; указанная справа дата также не вызывает вопросов. Остается разобраться, что такое $_.lastlogondate.

Как уже было сказано, where-object анализирует приходящие по конвейеру данные. Понятно, что утверждение (нечто) -le «1 January 2013» предполагает сопоставление этого (нечто) с указанной датой. Таким образом, данное (нечто) должно быть именно тем, что в данный момент приходит по конвейеру.

Для обозначения того, что передано по конвейеру, используется символ $_. Мы уже знаем, что PowerShell имеет переменные, позволяющие хранить временную информацию в памяти компьютера. Переменную можно узнать по первому символу – знаку доллара ($). Переменные можно создавать в ходе работы, но у PowerShell, как и у большинства сред построения сценариев, есть и встроенные переменные, например $true и $false, хранящие значения true и false. По аналогии логично было бы хранить текущее содержимое конвейера в переменной $pipeline, но вместо этого используется переменная $_, которая в данном случае хранит весь передаваемый по конвейеру объект – учетную запись пользователя.

Однако приведенный в нашем примере критерий предусматривает сопоставление с датой (1 января 2013 г.) не всего объекта пользователя, а лишь его свойства lastlogondate. Задачу извлечения лишь нужной информации решает добавление точки и имени свойства, в результате чего получается запись $_.lastlogondate. Итак, усовершенствованный с помощью where-object запрос будет выглядеть следующим образом:

get-aduser –f * -pr lastlogondate |? {$_.lastlogondate -le «1 January 2012»} | select samaccountname,lastlogondate | sort lastlogondate

С помощью where-object и $_ можно строить любые виды фильтров. Например, вывести имена всех пользователей, чье имя (SamAccountName) начинается с F, позволяет такой запрос:

get-aduser -f * | where {$_.samaccountname -like «f*"}

Может возникнуть вопрос: зачем было тратить столько времени на обсуждение параметра -filter команды get-aduser? Почему бы не применять для всех запросов единую форму:

get-aduser -f * | where {$_. -like»"}

С технической точки зрения, для этого нет противопоказаний, кроме одного: такой подход может привести к излишней трате полосы пропускания и времени сервера. Команда get-aduser с фильтром посылает команду контроллеру домена (DC), и DC возвращает лишь небольшое подмножество AD. Когда же результат get-aduser -f * подается на вход where-object, у DC запрашиваются все учетные записи пользователей, после чего локальный процессор отфильтровывает их, оставляя только нужные данные. Таким образом, where-object – отличный универсальный инструмент, однако следует избегать его применения, когда у исходной команды get-whatever уже есть встроенный фильтр.

Пока не буду больше ничего писать про новые командлеты в PowerShell V2 CTP3, а вернусь к истории — 1.0. Как показала практика, функции в скриптах администраторов завоевали очень высокую популярность и этому есть причина — функции позволяют однажды написать блок кода и потом его использовать много раз. Но не все знают всех возможностей функций и их разновидностей в PowerShell. Сегодня мы поговорим о том, на чём чаще всего спотыкаются начинающие пользователи PowerShell.

Аргументы в функциях

В общем смысле функции строятся по такому принципу:

functionFunctionName($arg1,$arg2,$argN){scriptoblock}

сначала мы говорим, что это будет функция и даём ей имя. В скобках указываем список принимаемых аргументов и после, в фигурных скобках указываем блок кода, который будет исполняться при вызове функций. Но функция сама по себе малоинтересна. Как правило в неё передаются какие-то данные и мы их должны как-то получать внутри функции. Данные в функции мы можем передавать двумя методами:

  • используя список аргументов (как в указанном примере)
  • по конвейеру

в первом случае всё просто. Если при объявлении функции мы указываем список аргументов, то при вызове функции эти переменные будут принимать значения. Возьмём простой пример:

functionabc($a,$b,$c){Write-Host'$a = '$aWrite-Host'$b = '$bWrite-Host'$c = '$c}

[vPodans] function abc ($a, $b, $c) { >> Write-Host ‘$a = ‘ $a >> Write-Host ‘$b = ‘ $b >> Write-Host ‘$c = ‘ $c >> } >> [vPodans] abc arg1 arg2 arg3 $a = arg1 $b = arg2 $c = arg3 [vPodans]

Чтобы вызвать функцию — достаточно написать её название и разделяя проблелом передавать ей значения. Вот здесь кроется первая частая ошибка начинающих при работе с PowerShell. Дело в том, что в некоторых языках программирования функции вызываются иначе: functionname (arg1, arg2, argN). В PowerShell же формат вызова функций вот такой: functionname arg1 arg2 argN. При объявлении функции указывать список принимаемых аргументов не обязательно (но рекомендуется для читаемости скрипта). В таком случае все аргументы будут помещены в специальную переменную $args, которая будет являться массивом аргументов. Но кроме аргументов в функции можно передавать параметры-ключи, как в командлетах (например, -Verbose, -WhatIf и т.д.). Это делается при помощи указания типа аргумента. Данный тип называется [switch]:

functionabc($a,$b,[switch]$parameter){Write-Host'$a = '$aWrite-Host'$b = '$bWrite-Host'parameter switch status = '$parameter}

[vPodans] function abc ($a, $b, [switch]$parameter) { >> Write-Host ‘$a = ‘ $a >> Write-Host ‘$b = ‘ $b >> Write-Host ‘parameter switch status = ‘ $parameter >> } >> [vPodans] abc 1 5 -parameter $a = 1 $b = 5 parameter switch status = True [vPodans] abc 1 5 $a = 1 $b = 5 parameter status = False [vPodans]

это очень удобно, когда одним ключом по аналогии с командлетом можно выбирать режим работы функции. Просто в фнукции проверяете статус ключа True или False и в зависимости от этого выбираете режим.

Конвейер и функции

Но часто нам удобней передавать данные в функцию для обработки по конвейеру. И мы безусловно можем так делать. Но тут есть свои тонкости.

[vPodans] function sum {$_ * 2} [vPodans] 1..5 | sum [vPodans]

Мы захотели просто умножить каждое число на 2. Но результата нету. Это вторая частая ошибка начинающих пользователей, которые путают функцию с конвейерным циклом Foreach-Object:

[vPodans] function sum {$_ * 2} [vPodans] 1..5 | %{sum} 2 4 6 8 10 [vPodans]

а вот теперь получили ожидаемый результат. Дело в том, что в функцию данные поступают не по мере появления их на входе конвейера, а только когда конвейер будет заполнен. Пока конвейер наполняется данными, они помещаются в специальную переменную $input в виде массива. И только после этого начинает исполняться само тело функции. Смотрим:

[vPodans] function input {$input} [vPodans] 1..5 | input 1 2 3 4 5 [vPodans]

Однако, данный метод очень непроизводителен, когда требуется произвести некоторую операцию над каждым элементом конвейера.

Get-Aduser -Filter не принимает переменную

Поскольку мы должны сначала ждать, пока по конвейеру будут собраны все данные в переменную $input и только потом начнётся сама обработка. Т.к. переменная $input является массивом, то мы не можем прямо к ней использовать переменную текущего элемента $_. Как вариант, можно в самой функции разобрать переменную $input циклом и получить требуемый результат:

[vPodans] function sum {$input | %{$_ * 2}} [vPodans] 1..5 | sum 2 4 6 8 10 [vPodans]

Задача хоть и решена, но кроме потери производительности у нас ещё вырос объём кода. Что тоже не есть хорошо. Чтобы избавиться от переменной $input можно использовать этап функции — Process. Что это такое и с чем его едят можно узнать из замечательного поста Дмитрия Сотникова — $input Gotchas. Материал по ссылке излож
ен достаточно подробно и он будет понятен даже тем, у кого есть хотя бы базовые навыки английского языка. Итак:

[vPodans] function sum {process {$_ * 2}} [vPodans] 1..5 | sum 2 4 6 8 10 [vPodans]

на этапе Process мы отказываемся в дополнительном разборе переменной $input, поскольку этап Process уже начинает исполняться при поступлении первого элемента на вход конвейера. Следовательно мы получаем выигрыш в скорости работы. Но для таких вещей, как обработка каждого элемента в функции в PowerShell есть одна разновидность функции и называется фильтр! По сути фильтр является той же функцией, которая помещена в цикл Foreach-Object. Фильтры в PowerShell используются так же, как и функции:

filterFilterName($arg1,$arg2){scriptoblock}

[vPodans] filter sum {$_ * 2} [vPodans] 1..5 | sum 2 4 6 8 10 [vPodans]

это то же самое, что и:

[vPodans] function sum {$_ * 2} [vPodans] 1..5 | %{sum} 2 4 6 8 10 [vPodans]

Как видите, вариантов решений задачи в функциях существует много и каждый может использовать тот, что ему по душе. Можно сказать, что это мелочи? Да, можно. Но именно вот такие мелочи будут влиять на эстетическую красоту, производительность и ресурсопотребление ваших скриптов в работе. Причём разница в производительности и ресурсопотреблении может доходить до 100(!) раз, в зависимости от выбранного метода. Об этом я уже говорил в своём предыдущем блоге на примере циклов: Foreach, Foreach-Object и оптимизация циклов в PowerShell.

Часто возникает ситуация когда необходимо узнать имя пользователя  в данный момент времени работающий на компьютере в домене.

PowerShell. Работа с файлами, импорт и экспорт объектов в текстовые файлы.

Как это выяснить с помощью PowerShell и WMI ?

Способ 1.

Введем следующий код в PowerShell  (измените имя COMPUTERNAME на имя целевой машины).

Get-WmiObject Win32_ComputerSystem -ComputerName «COMPUTERNAME» | Select-Object -ExpandProperty UserName

Для работы вышеуказанного способа вам понадобятся права администратора на целевой машине.

Способ 2.

Другой вариант, которым вы можете это сделать, является использование wmic . Введите ниже в окно командной строки, изменив имя COMPUTERNAME на целевую машину;

wmic.exe /node:COMPUTERNAME computersystem get username

Клиент удаленного рабочего стола.

Также часто требуется знать с какого компьютера подключился терминальный пользователь. Самый быстрый способ – запустить диспетчер задач.

Пуск -> Выполнить -> taskmgr.exe – > Пользователи.

PowerShell — это новая командная оболочка для Windows, которая по задумкам Microsoft должна вытеснить и заменить cmd. По-умолчанию, эта оболочка уже идет в составе Windows 7 и выше. Если у вас более старая операционная система или вы просто хотите скачать более свежую версию PowerShell, сделать это можно здесь: https://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx

Как запустить скрипт PowerShell?

Есть несколько различных способов запуска скрипта, ниже приведены основные:

  1. Запустить оболочку PowerShell и в ней запустить скрипт (ввести путь до файла и имя файла, например, так: C:\Scripts\test.ps1, или перейти в папку скрипта командой cd C:\Scripts и запустить его командой .\test.ps1)Оболочку можно найти и запустить множеством способов. Один из способов — через меню «Пуск». Для Windows 7 — нужно зайти во «Все программы» — «Стандартные» — «Windows PowerShell» и запустить оболочку «Windows PowerShell». Для Windows 10 — нужно найти группу на букву «W» и в ней вы найдете «Windows PowerShell».
  2. Запустить «Интегрированную среду сценариев Windows PowerShell ISE» — это программа — среда разработки, позволяющая редактировать и отлаживать скрипты PowerShell, которая так же есть по-умолчанию вместе с самим PowerShell. Запустив ее, нужно просто нажать кнопку «Открыть» или зайти в меню Файл — Открыть и выбрать нужный скрипт, затем нажать F5 или кнопку «Выполнить скрипт».Найти Windows PowerShell ISE можно там же, где и оболочку PowerShell — в меню «Пуск».
  3. Запустить стандартную коммандную строку и в ней написать:
    powershell -file <имя_скрипта> (пример: powershell -file myscript.ps1)

Если вы раньше не запускали скрипты PowerShell, то скорее всего, вы получите сообщение: Не удается загрузить файл <имя_скрипта>, так как выполнение скриптов запрещено для данной системы.

Введите «get-help about_signing» для получения дополнительных сведений. Связано это с тем, что из соображений безопасности и недопущения случайного выполнения вредоносного кода, все скрипты должны быть подписаны цифровой подписью.

Как разрешить выполнение неподписанного скрипта PowerShell?

1.

Active Directory PowerShell – Расширенный фильтр (Часть 2)

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

Set-ExecutionPolicy RemoteSigned -Scope Process

2. При запуске из стандартной коммандной строки использовать параметр -executionpolicy, т.е. запускать скрипт так:

powershell -executionpolicy RemoteSigned -file <имя_скрипта>

Оба способа устанавливают политику только для текущего сеанса, при этом, политика безопасности выполнения скриптов PowerShell, прописанная в реестре, не будет изменена и останется прежней. Если вы хотите поменять политику безопасности выполнения скриптов «на постоянно», то используйте такой способ:

3. Разрешить запуск навсегда: запустить оболочку PowerShell от имени «Администратора», затем выполните команду:

Set-ExecutionPolicy RemoteSigned

Однако, я бы не рекомендовал такой способ, чтобы не подвергать ваш компьютер возможным угрозам, т.к. так вы разрешаете выполнение скриптов всем и всегда.

Примечание: Если скрипт был загружен из интернета, то чтобы избежать запроса на подтверждение запуска, нужно вместо RemoteSigned использовать Bypass — полное отключение любых запросов и предупреждений.

Как запустить скрипт PowerShell в фоновом режиме?

Для этого достаточно использовать параметр запуска -WindowStyle, который может принимать значения: Normal, Minimized, Maximized и Hidden. Таким образом, чтобы запустить неподписанный скрипт в фоновом режиме, нужно выполнить команду:

powershell -executionpolicy RemoteSigned -WindowStyle Hidden -file <имя_скрипта>

Так же можно еще при желании добавить -NonInteractive, чтобы скрипт не задавал никаких вопросов. Таким образом, скрипт выполнится незаметно для пользователя. Будmте внимательны, используя такой способ.

Запуск скрипта PowerShell c параметрами

Собственно запуск нужно делать как если бы вы запускали обычную программу или bat-файл с параметрами. Например, для запуска скрипта с параметрами из командной, можно написать такую команду:

powershell -executionpolicy RemoteSigned -file <имя_скрипта> param1 param2 «еще один текстовый параметр»

В самом скрипте вы можете получить эти параметры так:

param ($var1, $var2, $var3) echo $var1, $var2, $var3

В интегрированной среде PowerShell ISE запустить скрипт с параметрами можно аналогично, используя область команд.

Как запустить скрипт PowerShell с помощью ярлыка?

Осуществить такую задачу можно двумя способами:

  1. Создать bat/cmd файл, в котором прописать команду для запуска скрипта (с параметрами вы ознакомились выше)
  2. Создать ярлык на PowerShell, который можно найти в папке c:\Windows\System32\WindowsPowerShell\v<версия>\ и в свойствах ярлыка в поле «Объект» дописать необходимые параметры.

Таким образом, например, чтобы запустить скрипт powershell при входе пользователя, можно просто создать ярлык, как описано во 2-м пункте и поместить его в автозагрузку. Так же, создание ярлыка одним из способов выше позволит легко запустить скрипт от имени администратора или от имени любого другого пользователя как обычную программу.

Скриптовый язык PowerShell — довольно мощный инструмент для решения различных задач, но его можно использовать не только для хороших вещей, но и во вред, поэтому, пользуйтесь им с умом 😉

 

Категория: Windows PowerShell

Аргументы в функциях

TL;DR:

Не используйте — использовать , чтобы ссылаться на текущий домашний каталог пользователя, обычно внутри :

Или, желательно, используйте командлет PowerShell :

Примечание:
* Типы PowerShell и .NET принимают и взаимозаменяемо как разделители путей; с целью возможной кросс-платформенной совместимости, выберите .
* Строго говоря, поскольку передается в в режиме аргумента (стиль командной строки), в этом случае нет необходимости включать (try ), но в хорошая привычка формироваться, потому что она работает в более широком спектре сценариев.


PowerShell не полностью эквивалентен в Unix (в POSIX-подобных оболочках) и может не работать так, как вы ожидаете, в PowerShell:

Как объясняется в этой статье TechNet [1] в PowerShell ссылается на домашнее местоположение, определяемое текущим провайдером привода местоположения,, которое:

  • может быть или не быть файловой системой.
  • может быть или не быть определен.

В Windows рассмотрим следующий пример, в котором используется поставщик диска реестра:

что приводит к следующей ошибке:

Как вы можете видеть, поскольку текущее местоположение находилось на диске поставщика реестра, интерпретировалась как идея поставщика исходного местоположения, которая, однако, не определяется.

Дополнительная важная разница:

  • В Unix, — это функция оболочки: она должна использоваться без кавычек, и в этом случае она расширяется до полного, литерального home-каталога оболочкой, перед Целевая команда видит путь, так что целевая команда видит литеральный путь и не нуждается в значении , и, по сути, стандартные утилиты не знают о , которые вы можете проверить, противопоставив (OK) с помощью (пытается перечислить файл /dir буквально с именем ).

  • В PowerShell — это функция провайдера PowerShell: передается как командлеты привода-провайдера, такие как , и они интерпретируют как относящееся к текущему местоположению домашнего диска. Внешние утилиты (например, в Windows), а .NET Framework не соответствуют этому соглашению и поэтому интерпретируют как литеральное имя файла.


В отличие от этого, автоматическая переменная является эквивалентом PowerShell Unix , с добавлением гибкость:

В то время как Unix должен быть некорректным для того, чтобы развернуть его в домашний каталог пользователя, переменная автоматического PowerShell может ссылаться и на строки с двойными кавычками (как часть нормального расширения строки (интерполяция)).


Наконец, типы .NET, такие как , не поддерживают ни , ни , но используя , PowerShell гарантирует, что заменяется на фактический, буквальный путь к домашней директории до того, как строка пути передается методу .NET.


[1] и , официальные разделы справки по теме, должны содержать информацию о ,  но на момент написания этого не делайте.

ответ дан mklement0 21 февр.

'18 в 6:56

источникподелиться

PowerShell Do…While Loop

 PowerShell Loops Featuring Do.. While… Until

PowerShell has a variety of looping structures to iterate instructions, this page focuses on the Do…While conditional construction.

One of the key jobs in scripting is looping, let us see what each of the keywords 'Do', 'While' and 'Until' have to offer when tackling a repetitive job.

PowerShell Do…While Loops

 ♣

Example: Waiting for User Input to Guess a Word

These two examples prompt the user to guess a word. 'Do' initiates 'Read-Host'.  'If and Else' deal with the logic of a correct, or incorrect guess; the 'Do' section loops until the user guesses correctly, or gives-in and types 'n'.

Do Until

The logic of this loop is to execute the  Do {block}until(the condition is true).  As usual in PowerShell, pay close attention to the style of brackets, the curly brackets or parentheses are guiding you to write the correct code.

Clear-Host
$strPassword ="123"
$strQuit = "Not yet"
Do {
$Guess = Read-Host "`n Guess the Password"
if($Guess -eq $StrPassword)
{" Correct guess"; $strQuit ="n"}
   else{
     $strQuit = Read-Host " Wrong `n Do you want another guess? (Y/N)"
         }
      } # End of 'Do'
Until ($strQuit -eq "N")
"`n Ready to do more stuff…"

Trap: Don't try: Until ($strQuit = "N").  What you need here is -eq, this is PowerShell's way of comparing two values.

Do While

The logic of 'Do … While' is the opposite of the Do Until. {Execute the block statement} while the (condition is true)

Clear-Host
$strPassword ="house"
$strQuit = "Guess again"
Do {
$Guess = Read-Host "`n Guess the Password"
if($Guess -eq $StrPassword)
{" Correct guess"; $strQuit ="n"}
   else{
     $strQuit = Read-Host " Wrong `n Do you want another guess? (Y/N)"
         }
      } # End of 'Do'
While ($strQuit -ne "N")
"`n Ready to do more stuff…"

Note 1: There are only two significant difference between these two examples:
Until ($strQuit -eq "N")
While ($strQuit -ne "N")

PowerShell's 'While' on Its Own — No Explicit 'Do'

In some ways this method employs the more traditional approach with the (condition) followed by the {Block command}.  Clearly, PowerShell's While loop is simpler and more basic than the 'Do … While' construction above.

Clear-Host
$strPassword ="house"
$strQuit = "Guess again"
While ($strQuit -ne "N") {
$Guess = Read-Host "`n Guess the Password"
If($Guess -eq $StrPassword)
{" Correct guess"; $strQuit ="n"}
   else{
     $strQuit = Read-Host " Wrong `n Do you want another guess?

Get-Aduser -Filter не принимает переменную

(Y/N)"
         }
      } # End of block statement
"`n Ready to do more stuff…"

Note 2: In this example the 'While' clause is at the beginning instead of the end.

Guy Recommends:  A Free Trial of the Network Performance Monitor (NPM) v11.5

SolarWinds’ Network Performance Monitor will help you discover what’s happening on your network.  This utility will also guide you through troubleshooting; the dashboard will indicate whether the root cause is a broken link, faulty equipment or resource overload.

What I like best is the way NPM suggests solutions to network problems.  Its also has the ability to monitor the health of individual VMware virtual machines.  If you are interested in troubleshooting, and creating network maps, then I recommend that you try NPM now.

Download a free trial of Solarwinds’ Network Performance Monitor

PowerShell's Simple 'For' Loop

PowerShell provides four or five different looping constructions, here is a simple method using the keyword 'For'.  As usual there is a (condition) and {Block Statement}.

The speciality of this loop is the <init> and <repeat> sections.

Here is the syntax:
For (<init>; <condition>; <repeat>) {<command_block>}

Example: Times Table for 125

For ($i = 125; $i -le 1000; $i+=125) { $i }

For (<init> ; <condition>; <repeat>) { 125 * 1,2,3,…8}

One side-effect of the For loop is that it always returns the <init> before it tests for the condition.  The <repeat> modifies the $i variable, which is then tested inside the <condition> of the next cycle.

Researching PowerShell's Loops

Clear-Host
Get-Help about_For
# Also
# Get-Help about_While

See also the Foreach-Object Cmdlet

Summary of PowerShell Do.. While… Until

PowerShell supplies at least four types of loops to cater for a variety of script logic.  Do keep an eye on the brackets, for instance the conditional elements, (parenthesis brackets) for the condition and {braces} for the command block.

If you like this page then please share it with your friends

 


See more Windows PowerShell flow control examples

• PowerShell Switch Statement  • PowerShell Real-life Techniques  • Free Permissions Analyzer

• Differences between For, ForEach and ForEach-Object  • PowerShell Loops  • PowerShell Home

• Conditional Operators   • Do While Loop  • PowerShell If Statement  • PowerShell Brackets

Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.

 

 *


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *