Skip to content

Syntax

Help

Get-Verb действия/глаголы, утвержденные для использования в командлетах
Get-Command *Language* поиск команды по имени
(Get-Command Get-Language).Module узнать к какому модулю принадлежит команда
Get-Command Get-Content | fl Module,DLL узнать принадлежность команды к модулю и dll
Get-Command -Module LanguagePackManagement отобразить список команд указанного модуля
(Get-Module LanguagePackManagement).ExportedCommands.Values отобразить список команд указанного модуля
Get-Language | Get-Member отобразить список методов команды (действия), объекты вывода и Event (события объектов: Click)
(Get-Help Get-Service).Aliases узнать псевдонимом команды
Get-Alias gsv узнать имя команды по псевдониму
Get-Help Get-Service синтаксис
Get-Help Get-Service -Parameter * описание всех параметров
Get-Help Get-Service -Online
Get-Help Get-Service -ShowWindow описание параметров в GUI с фильтрацией
Show-Command вывести список команд в GUI
Show-Command Get-Service список параметров команды в GUI
Invoke-Expression iex принимает текст для выполнения в консоли как команды
$PSVersionTable версия PowerShell
Set-ExecutionPolicy Unrestricted
Get-ExecutionPolicy
$Metadata = New-Object System.Management.Automation.CommandMetaData (Get-Command Get-Service) получить информацию о командлете
[System.Management.Automation.ProxyCommand]::Create($Metadata) исходный код функции

Object

Variable

$var = Read-Host "Enter" ручной ввод
$pass = Read-Host "Enter Password" -AsSecureString скрывать набор
$global:path = "\\path" задать глобальную переменную, например в функции
$using:srv использовать переменную текущей сесси в Invoke-сессии
Get-Variable отобразить все переменные
ls variable:/ отобразить все переменные
Get-Variable *srv* найти переменную по имени
Get-Variable -Scope Global отобразить все глобальные переменные
Get-Variable Error последняя команда с ошибкой
Remove-Variable -Name * очистить все переменные
$LASTEXITCODE содержит код вывода последней запущенной программы, например ping. Если код возврата положительный (True), то $LastExitCode = 0

ENV

Get-ChildItem Env: отобразить все переменные окружения
$env:PSModulePath директории импорта модулей
$env:userprofile
$env:computername
$env:username
$env:userdnsdomain
$env:logonserver
([DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).Name
[Environment]::GetFolderPath('ApplicationData')

History

Get-History история команд текущей сессии
(Get-History)[-1].Duration.TotalSeconds время выполнения последней команды
(Get-PSReadLineOption).HistorySavePath путь к сохраненному файлу с 4096 последних команд (из модуля PSReadLine)
Get-Content (Get-PSReadlineOption).HistorySavePath | Select-String Get поиск по содержимому файла (GREP)
Set-PSReadlineOption -MaximumHistoryCount 10000 изменить количество сохраняемых команд в файл
Get-PSReadLineOption | select MaximumHistoryCount
Set-PSReadlineOption -HistorySaveStyle SaveNothing отключить ведение журнала
F2 переключиться с InlineView на ListView

Clipboard

Set-Clipboard $srv скопировать в буфер обмена
Get-Clipboard вставить

Write

Write-Host -ForegroundColor Black -BackgroundColor Green "Test" -NoNewline
Write-Error Test
Foreach ($n in 1..100) {Write-Progress -Activity "Test Progress" -PercentComplete $n}

Array

$srv = @("server-01", "server-02") создать массив
$srv += @("server-03") добавить в массив новый элемент
$srv.Count отобразить кол-во элементов в массиве
Out-String построчный вывод

Index

$srv[0] вывести первое значение элемента массива
$srv[0] = Name замена элемента в массиве
$srv[0].Length узнать кол-во символов первого значения в массиве
$srv[10..100] срез

$array = "a","b","c","d"
$num = 0
foreach ($a in $array) {
$num += 1
$index = [array]::IndexOf($array, $a) # узнать номер индекса по зачению
$array[$index] = $num # пересобрать исходный массив
}

HashTable

$hashtable = @{"User" = "$env:username"; "Server" = "$env:computername"} # создать
$hashtable += @{"User2" = "$env:username"; "Server2" = "$env:computername"} # добавить ключи
$hashtable.Keys # список всех ключей
$hashtable["User"] # получить значение (Values) по ключу
$hashtable["User"] = "Test" # изменить
$hashtable.Remove("User") # удалить ключ

$Tag = @{$true = 'dev'; $false = 'prod'}[([System.Net.Dns]::GetHostEntry("localhost").HostName) -match '.*.TestDomain$']

Collections/List

$Collections = New-Object System.Collections.Generic.List[System.Object]
$Collections.Add([PSCustomObject]@{User = $env:username; Server = $env:computername})

PSCustomObject

$CustomObject = [PSCustomObject][ordered]@{User = $env:username; Server = $env:computername}
$CustomObject | Add-Member –MemberType NoteProperty –Name Arr –Value @(1,2,3) # добавить Property (свойство/стобец)
$CustomObject.Arr = @(1,3,5) # изменить содержимое
$CustomObject.PsObject.Properties.Remove('User') # удалить Property

Add-Member

$ScriptBlock = {Get-Service}
$CustomObject | Add-Member -Name "TestMethod" -MemberType ScriptMethod -Value $ScriptBlock # Добавить Method
$CustomObject | Get-Member
$CustomObject.TestMethod()

Class

Class CustomClass {
[string]$User
[string]$Server
Start([bool]$Param1) {
If ($Param1) {Write-Host "Start Function"}}
}

$Class = New-Object -TypeName CustomClass
$Class.User = $env:username
$Class.Server = $env:computername
$Class.Start(1)

Pipeline

$obj | Add-Member -MemberType NoteProperty -Name "Type" -Value "user" -Force добавление объкта вывода NoteProperty
$obj | Add-Member -MemberType NoteProperty -Name "User" -Value "admin" -Force изменеие содержимого для сущности объекта User
ping $srv | Out-Null перенаправить результат вывода в Out-Null

Select-Object

Get-Process | Select-Object -Property * отобразить все доступные объекты вывода
Get-Process | select -Unique "Name" удалить повторяющиеся значения в массиве
Get-Process | select -ExpandProperty ProcessName преобразовать из объекта-коллекции в массив (вывести содержимое без наименовая столбца)
(Get-Process | ? Name -match iperf).Modules список используемых модулей процессом

Expression

ps | Sort-Object -Descending CPU | select -first 10 ProcessName, # сортировка по CPU, вывести первых 10 значений (-first)
@{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}}, # затрачено процессорного времени в минутах
@{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}}, # делим байты на КБ
@{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}} # вычесть из текущего времени - время запуска, и удалить milisec

Select-String

$(ipconfig | Select-String IPv4) -replace ".+: " | Where-Object {$_ -match "^172."} узнать только IP
$Current_IP = Get-Content $RDCMan_RDG_PATH | Select-String $RDCMan_Display_Name -Context 0,1 получить две строки
$Current_IP = $Current_IP.Context.DisplayPostContext[0] -replace ".+<name>|<\/name>" забрать только вторую строку и удалить тэги

Format-Table/Format-List

Get-Process | ft ProcessName, StartTime -Autosize автоматическая группировка размера столбцов

Measure-Object

Get-Process | Measure | select Count кол-во объектов
Get-Process | Measure -Line -Word -Character кол-во строк, слов и Char объектов
Get-Process | Measure-Object PM -sum | Select-Object Count,@{Name="MEM_MB"; Expression={[int]($_.Sum/1mb)}} кол-во процессов и общий объем занятой памяти в МБайт

Compare-Object

Compare-Object -ReferenceObject (Get-Content -Path .\file1.txt) -DifferenceObject (Get-Content -Path .\file2.txt) сравнение двух файлов
$group1 = Get-ADGroupMember -Identity "Domain Admins"
$group2 = Get-ADGroupMember -Identity "Enterprise Admins"
Compare-Object -ReferenceObject $group1 -DifferenceObject $group2 -IncludeEqual
== нет изменений
<= есть изменения в $group1
=> есть изменения в $group2

Where-Object (?)

Get-Process | Where-Object {$_.ProcessName -match "zabbix"} фильтрация/поиск процессов по имени свойства объекта
Get-Process | where CPU -gt 10 | Sort-Object -Descending CPU вывести объекты, где значения CPU больше 10
Get-Process | where WS -gt 200MB отобразить процессы где WS выше 200МБ
Get-Service | where Name -match "zabbix" поиск службы
Get-Service -ComputerName $srv | Where {$_.Name -match "WinRM"} | Restart-Service перезапустить службу на удаленном компьютере
(Get-Service).DisplayName вывести значения свойства массива
netstat -an | where {$_ -match 443}
netstat -an | ?{$_ -match 443}
(netstat -an) -match 443

Sort-Object

Get-Process | Sort-Object -Descending CPU | ft обратная (-Descending) сортировка по CPU
$path[-1..-10] обратная сборка массива без сортировки

Last/First

Get-Process | Sort-Object -Descending CPU | select -First 10 вывести первых 10 объектов
Get-Process | Sort-Object -Descending CPU | select -Last 10 вывести последних 10 объектов

Group-Object

$Groups = Get-CimInstance -Class Win32_PnPSignedDriver |
Select-Object DriverProviderName, FriendlyName, Description, DriverVersion, DriverDate |
Group-Object DriverProviderName, FriendlyName, Description, DriverVersion, DriverDate
$(foreach ($Group in $Groups) {
    $Group.Group[0]
}) | Format-Table

Error

$Error выводит все ошибки текущего сеанса
$Error[0].InvocationInfo развернутый отчет об ошибке
$Error.clear()
$LASTEXITCODE результат выполнения последней команды (0 - успех)
exit 1 код завершения, который возвращается $LASTEXITCODE

Property

$srv.Count кол-во элементов в массиве
$srv.Length содержит количество символом строки переменной [string] или количество значений (строк) объекта
$srv.Chars(2) отобразить 3-й символ в строке
$srv[2] отобразить 3-ю строку в массиве

Method

$srv.Insert(0,"https://") добавить значение перед первым символом
$srv.Substring(4) удалить (из всего массива) первые 4 символа
$srv.Remove(3) удалить из всего массива все после 3 символа
$string = "123" создать строку
$int = [convert]::ToInt32($string) преобразовать строку в тип данных число
[string]::Concat($text,$num) объеденить переменные в одну строку
[string]::Join(":",$text,$num) объеденить используя разделитель
[string]::Compare($text,$num,$true) выдает 0 при совпадении или 1/-1 при несовпадении, $true (без учета регистра) или $false (с учетом регистра)
[string]::Equals($text,$num) производит сравнение двух строк и выдает $true при их совпадении или $false при несовпадении
[string]::IsNullOrEmpty($text) проверяет наличие строки, если строка пуста $true, если нет $false
[string]::IsNullOrWhiteSpace($text2) проверяет на наличие только символов пробел, табуляция или символ новой строки

DateTime

Get-TimeZone часовой пояс
[DateTime]::UtcNow время в формате UTC 0
(Get-Date).AddHours(-3)
$Date = (Get-Date -Format "dd/MM/yyyy hh:mm:ss")
$Date = Get-Date -f "dd/MM/yyyy" получаем тип данных [string]
[DateTime]$gDate = Get-Date "$Date" преобразовать в тип [DateTime]
[int32]$days=($fDate-$gDate).Days получить разницу в днях
"5/7/07" -as [DateTime] преобразовать входные данные в тип данных [DateTime]
New-TimeSpan -Start $VBRRP.CreationTimeUTC -End $VBRRP.CompletionTimeUTC получить разницу во времени

Measure-Command

(Measure-Command {ping ya.ru}).TotalSeconds узнать только время выполнения
(Get-History)[-1] | select @{Name="RunTime"; Expression={$_.EndExecutionTime - $_.StartExecutionTime}},ExecutionStatus,CommandLine посчитать время работы последней [-1] (select -Last 1) выполненной команды и узнать ее статус

Timer

$start_time = Get-Date зафиксировать время до выполнения команды
$end_time = Get-Date зафиксировать время по завершению
$time = $end_time - $start_time высчитать время работы скрипта
$min = $time.minutes
$sec = $time.seconds
Write-Host "$min минут $sec секунд"
$timer = [System.Diagnostics.Stopwatch]::StartNew() запустить таймер
$timer.IsRunning статус работы таймера
$timer.Elapsed.TotalSeconds отобразить время с момента запуска (в секундах)
$timer.Stop() остановить таймер

npp

pwsh -NoExit -ExecutionPolicy Unrestricted -WindowStyle Maximized -File "$(FULL_CURRENT_PATH)"

%AppData%\Notepad++ themes/shortcuts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
    <InternalCommands />
    <Macros>
        <Macro name="`+\+&gt;" Ctrl="yes" Alt="no" Shift="no" Key="190">
            <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="`" />
            <Action type="0" message="2451" wParam="0" lParam="0" sParam="" />
            <Action type="0" message="2451" wParam="0" lParam="0" sParam="" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="\" />
            <Action type="0" message="2300" wParam="0" lParam="0" sParam="" />
        </Macro>
    </Macros>
    <UserDefinedCommands>
        <Command name="PowerShell7" Ctrl="no" Alt="yes" Shift="no" Key="116">pwsh -NoExit -ExecutionPolicy Unrestricted -WindowStyle Maximized -File &quot;$(FULL_CURRENT_PATH)&quot;</Command>
    </UserDefinedCommands>
    <PluginCommands />
    <ScintillaKeys />
</NotepadPlus>

Parsing text to Markdown:
Macros: FnLeft+'+FnRight+FnRight+\s\\+Down
Replace: "# ","'"

.       # Обозначает любой символ
\       # Экранирующий символ. Символы которые экранируются: ^, [, ., $, {, *, (, ), \, +, |, ?, <, >
^       # Начало строки
$       # Конец строки
\n      # Новая строка
\d      # Любая цифра
\D      # Не цифра
\w      # Любая буква латиницы, цифра, или знак подчёркивания
\W      # Не латиница, не цифра, не подчёркивание
\s      # Пробел, табуляция, перенос строки
\S      # Не пробел
\b      # Граница слова. Применяется когда нужно выделить, что искомые символы являются словом, а не частью другого слова
\B      # Не граница слова
\<      # Начало слова
\>      # Конец слова
\A      # Начало текста
\Z      # Конец текста
*       # Повторитель. Означает что предшествующий символ может работать 0 и более раз
+       # Количество предшествующего не менее 1-го.
?       # Ограничитель. Не более одного раза
|       # Или. Соединяет несколько вариантов
()      # В круглые скобки заключаются все комбинации с "или" и поиск начала и конца строк
[ ]     # В квадратных скобках задаются символы к поиску, например [a-яА-Я], или [0-9]
[^ ]    # Исключает из поиска символы указанные в квадратных скобках
{ }     # В фигурных скобках указывается точное количество вхождений
\d{2}   # Найти две цифры
\d{2,4} # Найти две или четыре
{4,}    # Найти четыре и более

^\s{1,}#.+` поиск вначале строки комментария и пробел после него 1 или больше и любое кол-во символов

Regex

-replace "1","2" замена элементов в индексах массива (везде где присутствует 1, заменить на 2), для удаления используется только первое значение
-split " " преобразовать строку в массив, разделителем указан пробел, которой удаляется ($url.Split("/")[-1])
-join " " преобразовать массив (коллекцию) в единую строку (string), добавить разделителем пробел

-like *txt* поиск по маскам wildcard, выводит значение на экран
-match txt поиска по шаблонам, проверка на соответствие содержимого текста
-match "zabbix|rpc" условия, для поиска по нескольким словам
-NotMatch проверка на отсутствие вхождения

Matches

$ip = "192.168.10.1"
$ip -match "(\.\d{1,3})\.\d{1,2}" True
$Matches отобразить все подходящие переменные последнего поиска, которые входят и не входят в группы ()

$String = "09/14/2017 12:00:27 - mtbill_post_201709141058.txt 7577_Delivered: OK"
$String -Match ".*(?=\.txt)" | Out-Null
$Matches[0][-4..-1] -Join ""

$string.Substring($string.IndexOf(".txt")-4, 4) 2-й вариант (IndexOf)`

Форматирование (.NET method format)

[string]::Format("{1} {0}","Index0","Index1")
"{1} {0}" -f "Index0","Index1"
"{0:###-##-##}" -f 1234567 записать число в другом формате (#)
"{0:0000}" -f 123 вывести число в формате не меньше 4 знаков (0123)
"{0:P0}" -f (220/1000) посчитать в процентах (P)
"{0:P}" -f (512MB/1GB) сколько % составляет 512Мб от 1Гб
"{0:0.0%}" -f 0.123 умножить на 100%

$gp = Get-Process | sort cpu -Descending | select -First 10
foreach ($p in $gp) {
"{0} - {1:N2}" -f $p.processname, $p.cpu # округлить
}

Условный оператор

$rh = Read-Host
if ($rh -eq 1) {ipconfig} elseif ($rh -eq 2) {getmac} else {hostname}
Если условие if () является истенным ($True), выполнить действие в {}
Если условие if () является ложным ($False), выполнить действие не обязательного оператора else
Условие Elseif идёт после условия if для проверки дополнительных условий перед выполнение оператора else. Оператор, который первый вернет $True, отменит выполнение следующих дополнительных условий
Если передать переменную в условие без оператора, то будет проверяться наличие значения у переменной на $True/$False
if ((tnc $srv -Port 80).TcpTestSucceeded) {"Opened port"} else {"Closed port"}

Операторы

-eq равно (equal)
-ceq учитывать регистр
-ne не равно (not equal)
-gt больше (greater)
-ge больше или равно
-lt меньше (less)
-le меньше или равно
-in проверить на наличие (5 -in @(1,2,3,4,5))
-NOT логическое НЕТ !(Test-Path $path)
-and логическое И
-or логическое ИЛИ
if ((($1 -eq 1) -and ($2 -eq 2)) -or ($1 -ne 3)) {"$true"} else {"$false"} два условия: (если $1 = 1 и $2 = 2) или $1 не равно 3

Pipeline Operators

Write-Output "First" && Write-Output "Second" две успешные команды выполняются
Write-Error "Bad" && Write-Output "Second" первая команда завершается ошибкой, из-за чего вторая команда не выполняется
Write-Error "Bad" || Write-Output "Second" первая команда завершается ошибкой, поэтому выполняется вторая команда
Write-Output "First" || Write-Output "Second" первая команда выполнена успешно, поэтому вторая команда не выполняется

Invocation Operator

$addr = "8.8.8.8"
$ping = "ping"
& $ping $addr запускает текст как команду

& $ping $addr & запустить команду в фоне
(Get-Job)[-1] | Receive-Job -Keep

Специальные символы

\d число от 0 до 9 (20-07-2022 эквивалент: "\d\d-\d\d-\d\d\d\d")
\D обозначает любой символ, кроме цифры. Удаления всех символов, кроме цифр: [int]$("123 test" -replace "\D")
\w буква от "a" до "z" и от "A" до "Z" или число от 0 до 9
\s пробел, эквивалент: " "
\n новая строка
\b маска, определяет начало и конец целого словосочетания для поиска
. обозначает любой символ, кроме новой строки
\ экранирует любой специальны символ (метасимвол). Используется, если нужно указать конкретный символ, вместо специального ({ } [ ] / \ + * . $ ^ | ?)
+ повторяется 1 и более раз (\s+)
{1,25} квантификатор, указывает количество повторений символа слева на право (от 1 до 25 раз)
[] поиск совпадения любой буквы, например, [A-z0-9] от A до z и цифры от 0 до 9 ("192.168.1.1" -match "192.1[6-7][0-9]")

Якори

^ или \A определяет начало строки. $url -replace '^','https:'добавить в начало;$или\Zобозначают конец строки. $ip -replace "\d{1,3}$","0"(?=text)поиск слова слева. Пишем слева на право от искомого (ищет только целые словосочетания) "Server:\s(.{1,30})\s(?=$username)"(?<=text)поиск слова справа. $in_time -replace ".+(?<=Last)" удалить все до слова Last
(?!text) не совпадает со словом слева
(?<!text) не совпадает со словом справа

$test = "string"
$test -replace ".{1}$" удалить любое кол-во символов в конце строки
$test -replace "^.{1}" удалить любое кол-во символов в начале строки

Группы захвата

$date = '12.31.2021'
$date -replace '^(\d{2}).(\d{2})','$2.$1' поменять местами
$1 содержимое первой группы в скобках
$2 содержимое второй группы

DataType

$srv.GetType() узнать тип данных
$srv -is [string] проверка на соответствие типа данных
$srv -isnot [System.Object] проверка на несоответствие
[Object] массив (BaseType:System.Array)
[DateTime] формат времени (BaseType:System.ValueType)
[Bool]/[Boolean] логическое значение ($True/$False) или 1/0 (1 бит) наличие/отсуствие напряжения
[Byte] 8-битное (1 байт) целое число без знака (0..255)
[Int16] 16-битное знаковое целое число от -32767 до 32767 (тип данных WORD 0..65535)
[Int] 32-битное (4 байта) знаковое целое число от –2147483648 до 2147483647 (DWORD)
[Int64] 64-битное от -9223372036854775808 до 9223372036854775808 (LWORD)
[Decimal] 128-битное десятичное значение от –79228162514264337593543950335 до 79228162514264337593543950335
[Single] число с плавающей запятой (32-разрядное)
[Double] число с плавающей запятой с двойной точностью (64-разрядное)
[String] неизменяемая строка символов Юникода фиксированной длины (BaseType:System.Object)

Math

[math] | Get-Member -Static
[math]::Pow(2,4) 2 в 4 степени
[math]::Truncate(1.8) грубое округление, удаляет дробную часть
[math]::Ceiling(1.8) округляет число в большую сторону до ближайшего целого значения
[math]::Floor(-1.8) округляет число в меньшую сторону
[math]::Min(33,22) возвращает наименьшее значение двух значений
[math]::Max(33,22) возвращает наибольшее значение двух значений

Round

[double]::Round(87.5, 0) 88 (нечетное), в .NET по умолчанию используется округление в средней точке ToEven, где *.5 значения округляются до ближайшего четного целого числа.
[double]::Round(88.5, 0) 88 (четное)
[double]::Round(88.5, 0, 1) 89 (округлять в большую сторону)
[double]::Round(1234.56789, 2) округлить до 2 символов после запятой

ToString

(4164539/1MB).ToString("0.00") разделить на дважды на 1024/1024 и округлить до 3,97

Char

[Char] cимвол Юникода (16-разрядный)
$char = $srv.ToCharArray() разбить строку [string] на массив [System.Array] из букв

Module

psd1

@{
    RootModule        = "Get-Function.psm1"
    ModuleVersion     = "0.1"
    Author            = "Lifailon"
    CompanyName       = "Open Source Community"
    Copyright         = "Apache-2.0"
    Description       = "Function example"
    PowerShellVersion = "7.2"
    PrivateData       = @{
        PSData = @{
            Tags         = @("Function","Example")
            ProjectUri   = "https://github.com/Lifailon/PS-Commands"
            LicenseUri   = "https://github.com/Lifailon/Console-Translate/blob/rsa/LICENSE"
            ReleaseNotes = "Second release"
        }
    }
}

psm1

function Get-Function {
    <#
    .SYNOPSIS
    Описание
    .DESCRIPTION
    Описание
    .LINK
    https://github.com/Lifailon/PS-Commands
    #>
    param (
        [Parameter(Mandatory,ValueFromPipeline)][string]$Text,
        [ValidateSet("Test1","Test2")][string]$Provider = "Test1",
        [ValidateRange(1,3)][int]$Number = 2,
        [Switch]$Switch
    )
    Write-Host Param Text: $Text
    Write-Host Param Provider: $Provider
    Write-Host Param Number: $Number
    Write-Host Param Switch: $Switch
}

Get-Function Test

Switch

$MMM = Get-Date -UFormat "%m"
switch($MMM) {
    "01" {$Month = 'Jan'}
    "02" {$Month = 'Feb'}
    "03" {$Month = 'Mar'}
    "04" {$Month = 'Apr'}
    "05" {$Month = 'May'}
    "06" {$Month = 'Jun'}
    "07" {$Month = 'Jul'}
    "08" {$Month = 'Aug'}
    "09" {$Month = 'Sep'}
    "10" {$Month = 'Oct'}
    "11" {$Month = 'Nov'}
    "12" {$Month = 'Dec'}
}

function switch

Function fun-switch (
    [switch]$param
) {
    If ($param) {"yes"} else {"no"}
}

fun-switch -param

Bit

Двоичное    Десятичное
1           1
10          2
11          3
100         4
101         5
110         6
111         7
1000        8
1001        9
1010        10
1011        11
1100        12
1101        13
1110        14
1111        15
1 0000      16

Двоичное    Десятичное  Номер разряда
1           1           0
10          2           1
100         4           2
1000        8           3
1 0000      16          4
10 0000     32          5
100 0000    64          6
1000 0000   128         7
1 0000 0000 256         8

Из двоичного => десятичное (1-й вариант по таблице)
1001 0011 = 1000 0000 + 1 0000 + 10 + 1 = 128 + 16 + 2 + 1 = 147

2-й вариант
7654 3210 (разряды двоичного выражения) = (1*2^7)+(0*2^6)+(0*2^5)+(1*2^4)+(0*2^3)+(0*2^2)+(1*2^1)+(1*2^0) = 147
[math]::Pow(2,7) + [math]::Pow(2,4) + [math]::Pow(2,1) + [math]::Pow(2,0) = 147` исключить 0 и сложить степень

Из десятичного => двоичное (1-й вариант по таблице)
347 вычесть ближайшие 256 = 91 (+ 1 0000 0000 забрать двоичный остаток)
91  - 64  = 27 ближайшее 16 (+ 100 0000)
27  - 16  = 11 ближайшее 8 (+ 1 0000)
11  - 8   = 3  ближайшее 2 (+ 1000)
3   - 2   = 1 (+ 10)
1   - 1   = 0 (+ 1)
1 0101 1011

2-й вариант
Последовательное деления числа на 2, предворительно забирая остаток для получения четного числа в меньшую сторону
347 - 346 = остаток 1, (347-1)/2 = 173
173 - 172 = остаток 1, (172-1)/2 = 86
86  - 86  = остаток 0, 86/2 = 43
43  - 42  = остаток 1, (43-1)/2 = 21
21  - 20  = остаток 1, (21-1)/2 = 10
10  - 10  = остаток 0, 10/2 = 5
5   - 4   = остаток 1, (5-1)/2 = 2
2   - 2   = остаток 0, 2/2 = 1
1   - 2   = остаток 1, (1-1)/2 = 0
Результат деления записывается снизу вверх

Bit Convertor

function ConvertTo-Bit {
    param (
        [Int]$int
    )
    [array]$bits = @()
    $test = $true
    while ($test -eq $true) {
        if (($int/2).GetType() -match [double]) {
            $int = ($int-1)/2
            [array]$bits += 1
        }
        elseif (($int/2).GetType() -match [int]) {
            $int = $int/2
            [array]$bits += 0
        }
        if ($int -eq 0) {
            $test = $false
        }
    }
    $bits =  $bits[-1..-999]
    ([string]($bits)) -replace "\s"
}

ConvertTo-Bit 347

function ConvertFrom-Bit {
    param (
        $bit
    )
    [int]$int = 0
    $bits = $bit.ToString().ToCharArray()
    $index = ($bits.Count)-1
    foreach ($b in $bits) {
        if ($b -notlike 0) {
            $int += [math]::Pow(2,$index)
        }
    $index -= 1
    }
    $int
}

ConvertFrom-Bit 10010011

Get-Process pwsh | fl ProcessorAffinity привязка процесса к ядрам, представляет из себя битовую маску (bitmask), где каждому биту соответствует ядро процессора. Если для ядра отмечено сходство (affinity), то бит выставляется в 1, если нет — то в 0. Например, если выбраны все 16 ядер, то это 1111 1111 1111 1111 или 65535.
(Get-Process pwsh).ProcessorAffinity = 15 0000000000001111 присвоить 4 первых ядра
(Get-Process pwsh).ProcessorAffinity = 61440 1111000000000000 присвоить 4 последних ядра
(Get-Process pwsh).ProcessorAffinity = (ConvertFrom-Bit 1111000000000000)

Cycle

Foreach

$list = 100..110 создать массив из цифр от 100 до 110
foreach ($srv in $list) {ping 192.168.3.$srv -n 1 -w 50} $srv хранит текущий элемент из $list и повторяет команду до последнего элемента в массиве
$foreach.Current текущий элемент в цикле
$foreach.Reset() обнуляет итерацию, перебор начнется заново, что приводит к бесконечному циклу
$foreach.MoveNext() переход к следующему элементу в цикле

ForEach-Object (%)

100..110 | %{ping -n 1 -w 50 192.168.3.$_ > $null
if ($LastExitCode -eq 0) {Write-Host "192.168.3.$_" -ForegroundColor green
} else {
Write-Host "192.168.3.$_"-ForegroundColor Red}}
%  # передать цикл через конвеер (ForEach-Object)
$_ # переменная цикла и конвеера ($PSItem)
gwmi Win32_QuickFixEngineering | where {$_.InstalledOn.ToString() -match "2022"} | %{($_.HotFixID.Substring(2))} # gwmi создает массив, вывод команды передается where для поиска подходящих под критерии объектов. По конвееру передается в цикл для удаления первых (2) символов методом Substring из всех объектов HotFixID.

While

$srv = "yandex.ru"
$out2 = "Есть пинг"
$out3 = "Нет пинга"
$out = $false # предварительно сбросить переменную, While проверяет условие до запуска цикла
While ($out -eq $false){ # пока условие является $true, цикл будет повторяться
$out = ping -n 1 -w 50 $srv
if ($out -match "ttl") {$out = $true; $out2} else {$out = $false; $out3; sleep 1}
}

while ($True){ # запустить бесконечный цикл
$result = ping yandex.ru -n 1 -w 50
if ($result -match "TTL"){ # условие, при котором будет выполнен break
Write-Host "Сайт доступен"
break # остановит цикл
} else {Write-Host "Сайт недоступен"; sleep 1}
}

Try-Catch-Finally

Try {$out = pping 192.168.3.1}
Catch {Write-Warning "$($error[0])"} # выводит в случае ошибки (вместо ошибки)
finally {$out = "End"} # выполняется в конце в любом случае

Files

$file = [System.IO.File]::Create("$home\desktop\test.txt") создать файл
$file.Close() закрыть файл
[System.IO.File]::ReadAllLines("$home\desktop\test.txt") прочитать файл
$file = New-Object System.IO.StreamReader("$home\desktop\test.txt") файл будет занят процессом PowerShell
$file | gm
$file.ReadLine() построчный вывод
$file.ReadToEnd() прочитать файл целиком

Read/Write Bytes

$file = [io.file]::ReadAllBytes("$home\desktop\powershell.jpg") метод открывает двоичный файл, считывает его в массив байт и закрывает файл
[io.file]::WriteAllBytes("$home\desktop\tloztotk-2.jpg",$file) сохранить байты в файл (можно использовать для выгрузки двоичных файлов из БД)

Get-Content $home/desktop\test.txt -Wait аналог tail
Test-Path $path проверить доступность пути
Get-ChildItem $path -Filter *.txt -Recurse отобразить содержимое каталога (Alias: ls/gci/dir) и дочерних каталогов (-Recurse) и отфильтровать вывод
Get-Location отобразить текущие месторасположение (Alias: pwd/gl)
Set-Location $path перемещение по каталогам (Alias: cd/sl)
Invoke-Item $path открыть файл (Alias: ii/start)
Get-ItemProperty $env:userprofile\Documents\dns-list.txt | select FullName,Directory,Name,BaseName,Extension свойтсва файла
Get-ItemProperty -Path $path\* | select FullName,CreationTime,LastWriteTime свойства файлов содержимого директории, дата их создания и последнего изменения
New-Item -Path "C:\test\" -ItemType "Directory" создать директорию (Alias: mkdir/md)
New-Item -Path "C:\test\file.txt" -ItemType "File" -Value "Добавить текст в файл" создать файл
"test" > "C:\test\file.txt" заменить содержимое
"test" >> "C:\test\file.txt" добавить строку в файл
New-Item -Path "C:\test\test\file.txt" -Force ключ используется для создания отсутствующих в пути директорий или перезаписи файла если он уже существует
Move-Item перемещение объектов (Alias: mv/move)
Remove-Item "$path\" -Recurse удаление всех файлов внутри каталога, без запроса подверждения (Alias: rm/del)
Remove-Item $path -Recurse -Include "*.txt","*.temp" -Exclude "log.txt" удалить все файлы с расширением txt и temp ([Array]), кроме log.txt
Rename-Item "C:\test\*.*" "*.jpg" переименовать файлы по маске (Alias: ren)
Copy-Item копирование файлов и каталогов (Alias: cp/copy)
Copy-Item -Path "\\server-01\test" -Destination "C:\" -Recurse копировать директорию с ее содержимым (-Recurse)
Copy-Item -Path "C:\*.txt" -Destination "C:\test\" знак '\' в конце Destination используется для переноса папки внутрь указанной, отсутствие, что это новое имя директории
Copy-Item -Path "C:\*" -Destination "C:\test\" -Include '*.txt','*.jpg' копировать объекты с указанным расширением (Include)
Copy-Item -Path "C:\*" -Destination "C:\test\" -Exclude '*.jpeg' копировать объекты, за исключением файлов с расширением (Exclude)
$log = Copy-Item "C:\*.txt" "C:\test\" -PassThru вывести результат копирования (логирование) в переменную, можно забирать строки с помощью индексов $log[0].FullName

Clear-env-Temp-14-days

$ls = Get-Item $env:TEMP\*.tmp # считать все файлы с указанным расширением
$date = (Get-Date).AddDays(-14)
foreach ($l in $ls) {
    if ($l.LastWriteTime -le $date) {
        $l.FullName
        Remove-Item $l.FullName -Recurse
    }
}

Filehash

Get-Filehash -Algorithm SHA256 "$env:USERPROFILE\Documents\RSA.conf.txt"

Microsoft.PowerShell.Archive

Compress-Archive -Path $sourcepath -DestinationPath $dstpath -CompressionLevel Optimal архивировать
Expand-Archive .\powerlinefonts.zip разархивировать

Credential

$Cred = Get-Credential сохраняет креды в переменные $Cred.Username и $Cred.Password
$Cred.GetNetworkCredential().password извлечь пароль
cmdkey /generic:"TERMSRV/$srv" /user:"$username" /pass:"$password" добавить указанные креды аудентификации на на терминальный сервер для подключения без пароля
mstsc /admin /v:$srv авторизоваться
cmdkey /delete:"TERMSRV/$srv" удалить добавленные креды аудентификации из системы
rundll32.exe keymgr.dll,KRShowKeyMgr хранилище Stored User Names and Password
Get-Service VaultSvc служба для работы Credential Manager
Install-Module CredentialManager установить модуль управления Credential Manager к хранилищу PasswordVault из PowerShell
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls11,Tls12' для устаноки модуля
Get-StoredCredential получить учетные данные из хранилища Windows Vault
Get-StrongPassword генератор пароля
New-StoredCredential -UserName test -Password "123456" добавить учетную запись
Remove-StoredCredential удалить учетную запись
$Cred = Get-StoredCredential | where {$_.username -match "admin"}
$pass = $cred.password
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

Out-Gridview

Get-Service -cn $srv | Out-GridView -Title "Service $srv" -OutputMode Single –PassThru | Restart-Service перезапустить выбранную службу

Out-File

Read-Host –AsSecureString | ConvertFrom-SecureString | Out-File "$env:userprofile\desktop\password.txt" писать в файл. Преобразовать пароль в формат SecureString с использованием шифрования Windows Data Protection API (DPAPI)

Get-Content (gc/cat/type)

$password = gc "$env:userprofile\desktop\password.txt" | ConvertTo-SecureString читать хэш пароля из файла с помощью ключей, хранящихся в профиле текущего пользователя, который невозможно прочитать на другом копьютере

AES Key

$AESKey = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey)
$AESKey | Out-File "C:\password.key"
$Cred.Password | ConvertFrom-SecureString -Key (Get-Content "C:\password.key") | Set-Content "C:\password.txt" сохранить пароль в файл используя внешний ключ
$pass = Get-Content "C:\password.txt" | ConvertTo-SecureString -Key (Get-Content "\\Server\Share\password.key") расшифровать пароль на втором компьютере

WinEvent

Get-WinEvent -ListLog * отобразить все доступные журналы логов
Get-WinEvent -ListLog * | where RecordCount -ne 0 | where RecordCount -ne $null | sort -Descending RecordCount отобразить не пустые журналы с сортировкой по кол-ву записей
Get-WinEvent -ListProvider * | ft отобразить всех провайдеров приложений
Get-WinEvent -ListProvider GroupPolicy найти в какой журнал LogLinks {Application} пишутся логи приложения
Get-WinEvent -ListProvider *smb*
Get-WinEvent -ListLog * | where logname -match SMB | sort -Descending RecordCount найти все журналы по имени
Get-WinEvent -LogName "Microsoft-Windows-SmbClient/Connectivity"
Get-WinEvent -ListProvider *firewall*

Filter XPath/Hashtable

Get-WinEvent -FilterHashtable @{LogName="Security";ID=4624} найти логи по ID в журнале Security
Get-WinEvent -FilterHashtable @{LogName="System";Level=2} найти все записи ошибки (1 - критический, 3 - предупреждение, 4 - сведения)
Get-WinEvent -FilterHashtable @{LogName="System";Level=2;ProviderName="Service Control Manager"} отфильтровать по имени провайдера

([xml](Get-WinEvent -FilterHashtable @{LogName="Security";ID=4688} -MaxEvents 1).ToXml()).Event.EventData.Data отобразить все свойства, хранимые в EventData (Message)
Get-WinEvent -FilterHashtable @{logname="security";ID=4688} -MaxEvents 1 | select timecreated,{$_.Properties[5].value} отфильтровать время события и имя запущенного процесса

$query = '
<QueryList>
    <Query Id="0" Path="Security">
        <Select Path="Security">
            *[System[EventID=4688]] and 
            *[EventData[Data[@Name="NewProcessName"]="C:\Windows\System32\autochk.exe" or Data[@Name="NewProcessName"]="C:\Windows\System32\services.exe"]]
        </Select>
    </Query>
</QueryList>
'

Get-WinEvent -LogName Security -FilterXPath $query

Reboot

$query = '
<QueryList>
    <Query Id="0" Path="System">
        <Select Path="System">
            *[
            System[
            EventID=41 or
            EventID=1074 or
            EventID=1076 or
            EventID=6005 or
            EventID=6006 or
            EventID=6008 or
            EventID=6009 or
            EventID=6013
            ]
            ]
        </Select>
    </Query>
</QueryList>
'
Get-WinEvent -LogName System -FilterXPath $query

41  ` Система была перезагружена без корректного завершения работы.
1074` Система была корректного выключена пользователем или процессом.
1076` Следует за Event ID 6008 и означает, что первый пользователь (с правом выключения системы) подключившийся к серверу после неожиданной перезагрузки или выключения, указал причину этого события.
6005` Запуск "Журнала событий Windows" (Event Log). Указывает на включение системы.
6006` Остановка «Журнала событий Windows». Указывает на выключение системы.
6008` Предыдущее выключение системы было неожиданным.
6009` Версия операционной системы, зафиксированная при загрузке системы.
6013` Время работы системы (system uptime) в секундах.

Logon

$srv = "localhost"
$FilterXPath = '<QueryList><Query Id="0"><Select>*[System[EventID=21]]</Select></Query></QueryList>'
$RDPAuths = Get-WinEvent -ComputerName $srv -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" -FilterXPath $FilterXPath
[xml[]]$xml = $RDPAuths | Foreach {$_.ToXml()}
$EventData = Foreach ($event in $xml.Event) {
New-Object PSObject -Property @{
"Connection Time" = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'yyyy-MM-dd hh:mm K')
"User Name" = $event.UserData.EventXML.User
"User ID" = $event.UserData.EventXML.SessionID
"User Address" = $event.UserData.EventXML.Address
"Event ID" = $event.System.EventID
}}
$EventData | ft

EventLog

Get-EventLog -List отобразить все корневые журналы логов и их размер
Clear-EventLog Application очистить логи указанного журнала
Get-EventLog -LogName Security -InstanceId 4624 найти логи по ID в журнале Security

Defender

Import-Module Defender
Get-Command -Module Defender
Get-MpComputerStatus
(Get-MpComputerStatus).AntivirusEnabled статус работы антивируса

$session = NewCimSession -ComputerName hostname подключиться к удаленному компьютеру, используется WinRM
Get-MpComputerStatus -CimSession $session | fl fullscan* узнать дату последнего сканирования на удаленном компьютере

Get-MpPreference настройки
(Get-MpPreference).ScanPurgeItemsAfterDelay время хранения записей журнала защитника в днях
Set-MpPreference -ScanPurgeItemsAfterDelay 30 изменить время хранения
ls "C:\ProgramData\Microsoft\Windows Defender\Scans\History"
Get-MpPreference | select disable* отобразить статус всех видов проверок/сканирований
Set-MpPreference -DisableRealtimeMonitoring $true отключить защиту Defender в реальном времени (использовать только ручное сканирование)
Set-MpPreference -DisableRemovableDriveScanning $false включить сканирование USB накопителей
Get-MpPreference | select excl* отобразить список всех исключений
(Get-MpPreference).ExclusionPath
Add-MpPreference -ExclusionPath C:\install добавить директорию в исключение
Remove-MpPreference -ExclusionPath C:\install удалить из исключения
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1 -PropertyType DWORD -Force полностью отключить Windows Defender

Set-MpPreference -SignatureDefinitionUpdateFileSharesSources \\FileShare1\Updates для обновления из сетевой папки нужно предварительно скачать файлы с сигнатурами баз с сайта https://www.microsoft.com/security/portal/definitions/adl.aspx и поместить в сетевой каталог
Update-MpSignature -UpdateSource FileShares изменить источник обновлений (MicrosoftUpdateServer – сервера обновлений MS в интернете, InternalDefinitionUpdateServer — внутренний WSUS сервер)
Update-MpSignature обновить сигнатуры

Start-MpScan -ScanType QuickScan быстрая проверка или FullScan
Start-MpScan -ScanType FullScan -AsJob
Set-MpPreference -RemediationScheduleDay 1-7 выбрать дни, начиная с воскресенья или 0 каждый день, 8 - сбросить
Set-MpPreference -ScanScheduleQuickScanTime 14:00:00
Start-MpScan -ScanType CustomScan -ScanPath "C:\Program Files" сканировать выбранную директорию

Get-MpThreat история угроз и тип угрозы (ThreatName: HackTool/Trojan)
Get-MpThreatCatalog список известных видов угроз
Get-MpThreatDetection история защиты (активных и прошлые) и ID угрозы
Get-MpThreat -ThreatID 2147760253

ls "C:\ProgramData\Microsoft\Windows Defender\Quarantine\" директория хранения файлов в карантине
cd "C:\Program Files\Windows Defender\"
.\MpCmdRun.exe -restore -name $ThreatName восстановить файл из карантина
.\MpCmdRun.exe -restore -filepath $path_file

WindowsUpdate

Get-Hotfix | Sort-Object -Descending InstalledOn список установленных обновлений (информация из cimv2)
Get-Hotfix -Description "Security update"
Get-CimInstance Win32_QuickFixEngineering
Get-Command -Module WindowsUpdate
Get-WindowsUpdateLog
Get-Service uhssvc служба Microsoft Health Update Tools, которая отвечает за предоставление обновлений

Install-Module -Name PSWindowsUpdate -Scope CurrentUser
Import-Module PSWindowsUpdate
Get-Command -Module PSWindowsUpdate
Get-WindowsUpdate список обновлений для скачать и установить с сервера WSUS или Microsoft Update
Get-WindowsUpdate -Download загрузить все обновления
Get-WindowsUpdate –Install установить все обновления
Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -IgnoreReboot установить все обновления без перезагрузки
Get-WindowsUpdate -KBArticleID KB2267602, KB4533002 -Install
Get-WindowsUpdate -KBArticleID KB2538243 -Hide скрыть обновления, что бы они никогда не устанавливались
Get-WindowsUpdate –IsHidden отобразить скрытые обновления (Hide-WindowsUpdate)
Remove-WindowsUpdate -KBArticleID KB4011634 -NoRestart удалить обновление
Uninstall-WindowsUpdate удалить обновление
Add-WUServiceManager регистрация сервера обновления (Windows Update Service Manager)
Enable-WURemoting включить правила Windows Defender, разрешающие удаленное использование командлета PSWindowsUpdate
Get-WUApiVersion версия Windows Update Agent
Get-WUHistory список всех установленных обновлений (история обновлений)
Get-WUHistory | Where-Object {$_.Title -match "KB4517389"} поиск обновления
Get-WULastResults даты последнего поиска и установки обновлений
Get-WURebootStatus проверить, нужна ли перезагрузка для применения конкретного обновления
Get-WUServiceManager выводит источники обновлений
Get-WUInstallerStatus статус службы Windows Installer
Remove-WUServiceManager отключить Windows Update Service Manager

DISM

Get-Command -Module Dism -Name *Driver*
Export-WindowsDriver -Online -Destination C:\Users\Lifailon\Documents\Drivers\ извлечение драйверов из текущей системы (C:\Windows\System32\DriverStore\FileRepository), выгружает список файлов, которые необходимы для установки драйвера (dll,sys,exe) в соответствии со списком файлов, указанных в секции [CopyFiles] inf-файла драйвера.
Export-WindowsDriver -Path C:\win_image -Destination C:\drivers извлечь драйвера из офлайн образа Windows, смонтированного в каталог c:\win_image
$BackupDrivers = Export-WindowsDriver -Online -Destination C:\Drivers
$BackupDrivers | ft Driver,ClassName,ProviderName,Date,Version,ClassDescription список драйверов в объектном представлении
$BackupDrivers | where classname -match printer
pnputil.exe /add-driver C:\drivers\*.inf /subdirs /install установить все (параметр subdirs) драйвера из указанной папки (включая вложенные)

sfc /scannow проверить целостность системных файлов с помощью утилиты SFC (System File Checker), в случае поиска ошибок, попробует восстановить их оригинальные копии из хранилища системных компонентов Windows (каталог C:\Windows\WinSxS). Вывод работы логируется в C:\Windows\Logs\CBS с тегом SR
Get-ComputerInfo | select * подробная информация о системе (WindowsVersion,WindowsEditionId,Bios)
Get-WindowsImage -ImagePath E:\sources\install.wim список доступных версий в образе
Repair-WindowsImage -Online –ScanHealth
Repair-WindowsImage -Online -RestoreHealth восстановление хранилища системных компонентов
Repair-WindowsImage -Online -RestoreHealth -Source E:\sources\install.wim:3 –LimitAccess восстановление в оффлайн режиме из образа по номеру индекса

Scheduled

$Trigger = New-ScheduledTaskTrigger -At 01:00am -Daily 1:00 ночи
$Trigger = New-ScheduledTaskTrigger –AtLogon запуск при входе пользователя в систему
$Trigger = New-ScheduledTaskTrigger -AtStartup при запуске системы
$User = "NT AUTHORITY\SYSTEM"
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "$home\Documents\DNS-Change-Tray-1.3.ps1"
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -WindowStyle Hidden -File $home\Documents\DNS-Change-Tray-1.3.ps1"
Register-ScheduledTask -TaskName "DNS-Change-Tray-Startup" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force

Get-ScheduledTask | ? state -ne Disabled список всех активных заданий
Start-ScheduledTask DNS-Change-Tray-Startup запустить задание немедленно
Get-ScheduledTask DNS-Change-Tray-Startup | Disable-ScheduledTask отключить задание
Get-ScheduledTask DNS-Change-Tray-Startup | Enable-ScheduledTask включить задание
Unregister-ScheduledTask DNS-Change-Tray-Startup удалить задание
Export-ScheduledTask DNS-Change-Tray-Startup | Out-File $home\Desktop\Task-Export-Startup.xml экспортировать задание в xml
Register-ScheduledTask -Xml (Get-Content $home\Desktop\Task-Export-Startup.xml | Out-String) -TaskName "DNS-Change-Tray-Startup"

shutdown

shutdown /r /o перезагрузка в безопасный режим
shutdown /s /t 600 /c "Power off after 10 minutes" выключение
shutdown /s /f принудительное закрытие приложений
shutdown /a отмена
shutdown /r /t 0 /m \\192.168.3.100
Restart-Computer -ComputerName 192.168.3.100 -Protocol WSMan через WinRM
Restart-Computer –ComputerName 192.168.3.100 –Force через WMI
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Start\HideShutDown" -Name "value" -Value 1 скрыть кнопку выключения
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Start\HideRestart" -Name "value" -Value 1 скрыть кнопку перезагрузки

function Start-Shutdown {
    <#
    .SYNOPSIS
    Module for shutdown and restart the computer at a specified time
    .DESCRIPTION
    Example:
    # Start-Shutdown -Time "18:00"
    # Start-Shutdown -Restart -Time "18:00"
    # Start-Shutdown -Cancel
    .LINK
    https://github.com/Lifailon/PS-Commands
    #>
    param(
        [string]$Time,
        [switch]$Restart,
        [switch]$Cancel
    )
    if ($Time) {
        $currentDateTime = Get-Date
        $shutdownTime = Get-Date $Time
        if ($shutdownTime -lt $currentDateTime) {
            $shutdownTime = $shutdownTime.AddDays(1)
        }
        $timeUntilShutdown = $shutdownTime - $currentDateTime
        $secondsUntilShutdown = [math]::Round($timeUntilShutdown.TotalSeconds)
    }
    if ($Cancel) {
        Start-Process -FilePath "shutdown.exe" -ArgumentList "/a"
    } elseif ($Restart) {
        Write-Host "The computer will restart after $($timeUntilShutdown.Hours) hours and $($timeUntilShutdown.Minutes) minutes."
        Start-Process -FilePath "shutdown.exe" -ArgumentList "/r", "/f", "/t", "$secondsUntilShutdown"
    } else {
        Write-Host "The computer will shutdown after $($timeUntilShutdown.Hours) hours and $($timeUntilShutdown.Minutes) minutes."
        Start-Process -FilePath "shutdown.exe" -ArgumentList "/s", "/f", "/t", "$secondsUntilShutdown"
    }
}

LocalAccounts

Get-Command -Module Microsoft.PowerShell.LocalAccounts
Get-LocalUser список пользователей
Get-LocalGroup список групп
New-LocalUser "1C" -Password $Password -FullName "1C Domain" создать пользователя
Set-LocalUser -Password $Password 1C изменить пароль
Add-LocalGroupMember -Group "Administrators" -Member "1C" добавить в группу Администраторов
Get-LocalGroupMember "Administrators" члены группы

@("vproxy-01","vproxy-02","vproxy-03") | %{
icm $_ {Add-LocalGroupMember -Group "Administrators" -Member "support4"}
icm $_ {Get-LocalGroupMember "Administrators"}
}

SMB

Get-SmbServerConfiguration
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force отключить протокол SMB v1
Get-WindowsFeature | Where-Object {$_.name -eq "FS-SMB1"} | ft Name,Installstate модуль ServerManager, проверить установлен ли компонент SMB1
Install-WindowsFeature FS-SMB1 установить SMB1
Uninstall-WindowsFeature –Name FS-SMB1 –Remove удалить SMB1 клиента (понадобится перезагрузка)
Get-WindowsOptionalFeature -Online модуль DISM, для работы с компонентами Windows
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -Remove удалить SMB1
Set-SmbServerConfiguration –AuditSmb1Access $true включить аудит SMB1
Get-SmbConnection список активных сессий и используемая версия SMB (Dialect)
Get-SmbOpenFile | select ClientUserName,ClientComputerName,Path,SessionID список открытых файлов
Get-SmbShare список сетевых папок
New-SmbShare -Name xl-share -Path E:\test создать новую общую сетевую папку (расшарить)
-EncryptData $True включить шифрование SMB
-Description имя в сетевом окружении
-ReadAccess "domain\username" доступ на чтение
-ChangeAccess доступ на запись
-FullAccess полный доступ
-NoAccess ALL нет прав
-FolderEnumerationMode [AccessBased | Unrestricted] позволяет скрыть в сетевой папке объекты, на которых у пользователя нет доступа с помощью Access-Based Enumeration (ABE)
Get-SmbShare xl-share | Set-SmbShare -FolderEnumerationMode AccessBased ключить ABE для всех расшаренных папок
Remove-SmbShare xl-share -force удалить сетевой доступ (шару)
Get-SmbShareAccess xl-share вывести список доступов безопасности к шаре
Revoke-SmbShareAccess xl-share -AccountName Everyone –Force удалить группу из списка доступов
Grant-SmbShareAccess -Name xl-share -AccountName "domain\XL-Share" -AccessRight Change –force изменить/добавить разрешения на запись (Full,Read)
Grant-SmbShareAccess -Name xl-share -AccountName "все" -AccessRight Change –force
Block-SmbShareAccess -Name xl-share -AccountName "domain\noAccess" -Force принудительный запрет
New-SmbMapping -LocalPath X: -RemotePath \\$srv\xl-share -UserName support4 -Password password –Persistent $true подключить сетевой диск
-Persistent восстановление соединения после отключения компьютера или сети
-SaveCredential позволяет сохранить учетные данные пользователя для подключения в диспетчер учетных данных Windows Credential Manager
Stop-Process -Name "explorer" | Start-Process -FilePath "C:\Windows\explorer.exe" перезапустить процесс для отображения в проводнике
Get-SmbMapping список подключенных сетевых дисков
Remove-SmbMapping X: -force отмонтировать сетевой диск
$CIMSession = New-CIMSession –Computername $srv создать сеанс CIM (аудентификация на SMB)
Get-SmbOpenFile -CIMSession $CIMSession | select ClientUserName,ClientComputerName,Path | Out-GridView -PassThru | Close-SmbOpenFile -CIMSession $CIMSession -Confirm:$false –Force закрыть файлы (открыть к ним сетевой доступ)

Get-Acl

(Get-Acl \\$srv\xl-share).access доступ ACL на уровне NTFS
Get-Acl C:\Drivers | Set-Acl C:\Distr скопировать NTFS разрешения с одной папки и применить их на другую

NTFSSecurity

Install-Module -Name NTFSSecurity -force
Get-Item "\\$srv\xl-share" | Get-NTFSAccess
Add-NTFSAccess -Path "\\$srv\xl-share" -Account "domain\xl-share" -AccessRights Fullcontrol -PassThru добавить
Remove-NTFSAccess -Path "\\$srv\xl-share" -Account "domain\xl-share" -AccessRights FullControl -PassThru удалить
Get-ChildItem -Path "\\$srv\xl-share" -Recurse -Force | Clear-NTFSAccess удалить все разрешения, без удаления унаследованных разрешений
Get-ChildItem -Path "\\$srv\xl-share" -Recurse -Force | Enable-NTFSAccessInheritance включить NTFS наследование для всех объектов в каталоге

Storage

Get-Command -Module Storage
Get-Disk список логических дисков
Get-Partition отобразить разделы на всех дисках
Get-Volume список логичких разделов
Get-PhysicalDisk список физических дисков
Initialize-Disk 1 –PartitionStyle MBR инициализировать диск
New-Partition -DriveLetter D –DiskNumber 1 -Size 500gb создать раздел (выделить все место -UseMaximumSize)
Format-Volume -DriveLetter D -FileSystem NTFS -NewFileSystemLabel Disk-D форматировать раздел
Set-Partition -DriveLetter D -IsActive $True сделать активным
Remove-Partition -DriveLetter D –DiskNumber 1 удалить раздел
Clear-Disk -Number 1 -RemoveData очистить диск
Repair-Volume –driveletter C –Scan Check disk
Repair-Volume –driveletter C –SpotFix
Repair-Volume –driverletter C -Scan –Cimsession $CIMSession

iSCSI

New-IscsiVirtualDisk -Path D:\iSCSIVirtualDisks\iSCSI2.vhdx -Size 20GB создать динамический vhdx-диск (для фиксированного размера -UseFixed)
New-IscsiServerTarget -TargetName iscsi-target-2 -InitiatorIds "IQN:iqn.1991-05.com.microsoft:srv3.contoso.com" создать Target
Get-IscsiServerTarget | fl TargetName, LunMappings
Connect-IscsiTarget -NodeAddress "iqn.1995-05.com.microsoft:srv2-iscsi-target-2-target" -IsPersistent $true подключиться инициатором к таргету
Get-IscsiTarget | fl
Disconnect-IscsiTarget -NodeAddress "iqn.1995-05.com.microsoft:srv2-iscsi-target-2-target" -Confirm:$false отключиться

PS2EXE

Install-Module ps2exe -Repository PSGallery
Get-Module -ListAvailable список всех модулей
-noConsole использовать GUI, без окна консоли powershell
-noOutput выполнение в фоне
-noError без вывода ошибок
-requireAdmin при запуске запросить права администратора
-credentialGUI вывод диалогового окна для ввода учетных данных
Invoke-ps2exe -inputFile "$home\Desktop\WinEvent-Viewer-1.1.ps1" -outputFile "$home\Desktop\WEV-1.1.exe" -iconFile "$home\Desktop\log_48px.ico" -title "WinEvent-Viewer" -noConsole -noOutput -noError

NSSM

$powershell_Path = (Get-Command powershell).Source
$NSSM_Path = (Get-Command "C:\WinPerf-Agent\NSSM-2.24.exe").Source
$Script_Path = "C:\WinPerf-Agent\WinPerf-Agent-1.1.ps1"
$Service_Name = "WinPerf-Agent"
& $NSSM_Path install $Service_Name $powershell_Path -ExecutionPolicy Bypass -NoProfile -f $Script_Path создать Service
& $NSSM_Path start $Service_Name запустить
& $NSSM_Path status $Service_Name статус
$Service_Name | Restart-Service перезапустить
$Service_Name | Get-Service статус
$Service_Name | Stop-Service остановить
& $NSSM_Path set $Service_Name description "Check performance CPU and report email" изменить описание
& $NSSM_Path remove $Service_Name удалить

Jobs

Get-Job получение списка задач
Start-Job запуск процесса
Stop-Job остановка процесса
Suspend-Job приостановка работы процесса
Resume-Job восстановление работы процесса
Wait-Job ожидание вывода команды
Receive-Job получение результатов выполненного процесса
Remove-Job удалить задачу

function Start-PingJob ($Network) {
$RNetwork = $Network -replace "\.\d{1,3}$","."
foreach ($4 in 1..254) {
$ip = $RNetwork+$4
# создаем задания, забираем 3-ю строку вывода и добавляем к выводу ip-адрес:
(Start-Job {"$using:ip : "+(ping -n 1 -w 50 $using:ip)[2]}) | Out-Null
}
while ($True){
$status_job = (Get-Job).State[-1] # забираем статус последнего задания
if ($status_job -like "Completed"){ # проверяем на выполнение (задания выполняются по очереди сверху вниз)
$ping_out = Get-Job | Receive-Job # если выполнен, забираем вывод всех заданий
Get-Job | Remove-Job -Force # удаляем задания
$ping_out
break # завершаем цикл
}}
}

Start-PingJob -Network 192.168.3.0
(Measure-Command {Start-PingJob -Network 192.168.3.0}).TotalSeconds 60 Seconds

ThreadJob

Install-Module -Name ThreadJob
Get-Module ThreadJob -list
Start-ThreadJob {ping ya.ru} | Out-Null создать фоновую задачу
Get-Job | Receive-Job -Keep отобразить и не удалять вывод
(Get-Job).HasMoreData если False, то вывод команы удален
(Get-Job)[-1].Output отобразить вывод последней задачи

function Start-PingThread ($Network) {
$RNetwork = $Network -replace "\.\d{1,3}$","."
foreach ($4 in 1..254) {
$ip = $RNetwork+$4
# создаем задания, забираем 3-ю строку вывода и добавляем к выводу ip-адрес:
(Start-ThreadJob {"$using:ip : "+(ping -n 1 -w 50 $using:ip)[2]}) | Out-Null
}
while ($True){
$status_job = (Get-Job).State[-1] # забираем статус последнего задания
if ($status_job -like "Completed"){ # проверяем на выполнение (задания выполняются по очереди сверху вниз)
$ping_out = Get-Job | Receive-Job # если выполнен, забираем вывод всех заданий
Get-Job | Remove-Job -Force # удаляем задания
$ping_out
break # завершаем цикл
}}
}

Start-PingThread -Network 192.168.3.0
(Measure-Command {Start-PingThread -Network 192.168.3.0}).TotalSeconds 24 Seconds

PoshRSJob

function Start-PingRSJob ($Network) {
$RNetwork = $Network -replace "\.\d{1,3}$","."
foreach ($4 in 1..254) {
$ip = $RNetwork+$4
(Start-RSJob {"$using:ip : "+(ping -n 1 -w 50 $using:ip)[2]}) | Out-Null
}
$ping_out = Get-RSJob | Receive-RSJob
$ping_out
Get-RSJob | Remove-RSJob
}

Start-PingRSJob -Network 192.168.3.0
(Measure-Command {Start-PingRSJob -Network 192.168.3.0}).TotalSeconds 10 Seconds

Regedit

Get-PSDrive список всех доступных дисков/разделов, их размер и веток реестра
cd HKLM:\ HKEY_LOCAL_MACHINE
cd HKCU:\ HKEY_CURRENT_USER
Get-Item получить информацию о ветке реестра
New-Item создать новый раздел реестра
Remove-Item удалить ветку реестра
Get-ItemProperty получить значение ключей/параметров реестра (это свойства ветки реестра, аналогично свойствам файла)
Set-ItemProperty изменить название или значение параметра реестра
New-ItemProperty создать параметр реестра
Remove-ItemProperty удалить параметр

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select DisplayName список установленных программ
Get-Item HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002 посмотреть содержимое Items
(Get-ItemProperty HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002)."New Signature" отобразить значение (Value) свойства (Property) Items
$reg_path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002"
$sig_name = "auto"
Set-ItemProperty -Path $reg_path -Name "New Signature" -Value $sig_name изменить или добавить в корне ветки (Path) свойство (Name) со значением (Value)
Set-ItemProperty -Path $reg_path -Name "Reply-Forward Signature" -Value $sig_name

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe]
"Debugger"="\"C:\\Windows\\System32\\Taskmgr.exe\""

Performance

lodctr /R пересоздать счетчиков производительности из системного хранилища архивов (так же исправляет счетчики для CIM, например, для cpu Win32_PerfFormattedData_PerfOS_Processor и iops Win32_PerfFormattedData_PerfDisk_PhysicalDisk)
(Get-Counter -ListSet *).CounterSetName вывести список всех доступных счетчиков производительности в системе
(Get-Counter -ListSet *memory*).Counter поиск по wildcard-имени во всех счетчиках (включая дочернии)
Get-Counter "\Memory\Available MBytes" объем свободной оперативной памяти
Get-Counter -cn $srv "\LogicalDisk(*)\% Free Space" % свободного места на всех разделах дисков
(Get-Counter "\Process(*)\ID Process").CounterSamples
Get-Counter "\Processor(_Total)\% Processor Time" –ComputerName $srv -MaxSamples 5 -SampleInterval 2 5 проверок каждые 2 секунды
Get-Counter "\Процессор(_Total)\% загруженности процессора" -Continuous непрерывно
(Get-Counter "\Процессор(*)\% загруженности процессора").CounterSamples

(Get-Counter -ListSet *интерфейс*).Counter найти все счетчики
Get-Counter "\Сетевой интерфейс(*)\Всего байт/с" отобразить все адаптеры (выбрать действующий по трафику)

$WARNING = 25
$CRITICAL = 50
$TransferRate = ((Get-Counter "\\huawei-mb-x-pro\сетевой интерфейс(intel[r] wi-fi 6e ax211 160mhz)\всего байт/с"
).countersamples | select -ExpandProperty CookedValue)*8
$NetworkUtilisation = [math]::round($TransferRate/1000000000*100,2)
if ($NetworkUtilisation -gt $CRITICAL){
Write-Output "CRITICAL: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"   
#exit 2     
}
if ($NetworkUtilisation -gt $WARNING){
Write-Output "WARNING: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"
#exit 1
}
Write-Output "OK: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"   
#exit 0

DSC

Import-Module PSDesiredStateConfiguration
Get-Command -Module PSDesiredStateConfiguration
(Get-Module PSDesiredStateConfiguration).ExportedCommands
Get-DscLocalConfigurationManager

Get-DscResource
Get-DscResource -Name File -Syntax синтаксис

Ensure = Present настройка должна быть включена (каталог должен присутствовать, процесс должен быть запущен, если нет – создать, запустить)
Ensure = Absent настройка должна быть выключена (каталога быть не должно, процесс не должен быть запущен, если нет – удалить, остановить)

Configuration TestConfiguraion
{
    Ctrl+Space
}

Configuration DSConfigurationProxy 
{
    Node vproxy-01 
    {
        File CreateDir
        {
            Ensure = "Present"
            Type = "Directory"
            DestinationPath = "C:\Temp"
        }
        Service StopW32time
        {
            Name = "w32time"
            State = "Stopped"` Running
        }
        WindowsProcess RunCalc
        {
            Ensure = "Present"
            Path = "C:\WINDOWS\system32\calc.exe"
            Arguments = ""
        }
        Registry RegSettings
        {
            Ensure = "Present"
            Key = "HKEY_LOCAL_MACHINE\SOFTWARE\MySoft"
            ValueName = "TestName"
            ValueData = "TestValue"
            ValueType = "String"
        }
#       WindowsFeature IIS
#       {
#            Ensure = "Present"
#            Name = "Web-Server"
#       }
    }
}

$Path = (DSConfigurationProxy).DirectoryName
Test-DscConfiguration -Path $Path | select * ResourcesInDesiredState - уже настроено, ResourcesNotInDesiredState - не настроено (не соответствует)
Start-DscConfiguration -Path $Path
Get-Job
$srv = "vproxy-01"
Get-Service -ComputerName $srv | ? name -match w32time # Start-Service
icm $srv {Get-Process | ? ProcessName -match calc} | ft # Stop-Process -Force
icm $srv {ls C:\ | ? name -match Temp} | ft rm`

Configuration InstallPowerShellCore {
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Node localhost {
        Script InstallPowerShellCore {
            GetScript = {
                return @{
                    GetScript = $GetScript
                }
            }
            SetScript = {
                [string]$url = $(Invoke-RestMethod https://api.github.com/repos/PowerShell/PowerShell/releases/latest).assets.browser_download_url -match "win-x64.zip"
                $downloadPath = "$home\Downloads\PowerShell.zip"
                $installPath = "$env:ProgramFiles\PowerShell\7"
                Invoke-WebRequest -Uri $url -OutFile $downloadPath
                Expand-Archive -Path $downloadPath -DestinationPath $installPath -Force
            }
            TestScript = {
                return Test-Path "$env:ProgramFiles\PowerShell\7\pwsh.exe"
            }
        }
    }
}

$Path = (InstallPowerShellCore).DirectoryName
Test-DscConfiguration -Path $Path
Start-DscConfiguration -Path $path -Wait -Verbose
Get-Job

oh-my-posh

Install

winget install JanDeDobbeleer.OhMyPosh -s winget
choco install oh-my-posh -y
scoop install https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/oh-my-posh.json
Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1'))

Themes

Get-PoshThemes
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/di4am0nd.omp.json" | Invoke-Expression
oh-my-posh init pwsh --config "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/cert.omp.json" | Invoke-Expression

New-Item -Path $PROFILE -Type File -Force
notepad $PROFILE
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/di4am0nd.omp.json" | Invoke-Expression

themes-performance

Install-Module themes-performance -Repository NuGet
Import-Module themes-performance
Set-PoshTheme -Theme System-Sensors # -Save
Set-PoshTheme -Theme System-Performance # -Save
Set-PoshTheme -Theme Pwsh-Process-Performance # -Save

Terminal-Icons

Install-Module -Name Terminal-Icons -Repository PSGallery
scoop bucket add extras
scoop install terminal-icons

notepad $PROFILE
Import-Module -Name Terminal-Icons

Использует шрифты, которые необходимо установить и настроить в параметрах профиля PowerShell: Nerd Fonts
Список шрифтов
Скачать и установить шрифт похожий на Cascadia Code - CaskaydiaCove

Pester

Source

Install-Module -Name Pester -Repository PSGallery -Force -AllowClobber
Import-Module Pester
$(Get-Module Pester -ListAvailable).Version

.Tests.ps1

function Add-Numbers {
    param (
        [int]$a,
        [int]$b
    )
    $a + $b
}
Describe "Add-Numbers" {
    Context "При сложении двух чисел" {
        It "Должна вернуться правильная сумма" {
            $result = Add-Numbers -a 3 -b 4
            $result | Should -Be 7
        }
    }
    Context "При сложении двух чисел" {
        It "Должна вернуться ошибка (5+0 -ne 4)" {
            $result = Add-Numbers -a 5 -b 0
            $result | Should -Be 4
        }
    }
}

function Get-RunningProcess {
    return Get-Process | Select-Object -ExpandProperty Name
}
Describe "Get-RunningProcess" {
    Context "При наличии запущенных процессов" {
        It "Должен возвращать список имен процессов" {
            $result = Get-RunningProcess
            $result | Should -Contain "svchost"
            $result | Should -Contain "explorer"
        }
    }
    Context "Когда нет запущенных процессов" {
        It "Должен возвращать пустой список" {
            # Замокать функцию Get-Process, чтобы она всегда возвращала пустой список процессов
            Mock Get-Process { return @() }
            $result = Get-RunningProcess
            $result | Should -BeEmpty
        }
    }
}