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="`+\+>" 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 "$(FULL_CURRENT_PATH)"</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¶
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'))
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¶
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
}
}
}