diff --git a/posh.txt b/posh.txt
index a90de8e..2ecb17c 100644
--- a/posh.txt
+++ b/posh.txt
@@ -2,11 +2,14 @@ PowerShell Commands
# Object
# Regex
+# DataType
+# Bit
# Files
# Credential
# WinEvent
# Firewall
# Defender
+# DISM
# Scheduled
# Network
# LocalAccounts
@@ -18,8 +21,9 @@ PowerShell Commands
# DFS
# Package
# Jobs
-# PowerCLI
-# EMShell
+# Hyper-V
+# VMWare/PowerCLI
+# Exchange/EMShell
# TrueNAS
# Veeam
# REST API
@@ -35,11 +39,11 @@ PowerShell Commands
# JSON
# YAML
# HTML
-# Git
# SQLite
# MySQL
# MSSQL
# InfluxDB
+# Telegraf
# Elasticsearch
# CData
# ODBC
@@ -49,9 +53,13 @@ PowerShell Commands
# Performance
# SNMP
# Zabbix
+# OpenSSH
# WinRM
-# Ansible
+# pki
# DSC
+# Git
+# Ansible
+# Jenkins
### Help
Get-Verb # действия/глаголы, утвержденные для использования в командлетах
@@ -127,6 +135,14 @@ $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"} # создать
@@ -231,6 +247,33 @@ Get-Process | Sort-Object -Descending CPU | select -Last 10 # вывести п
pwsh -NoExit -ExecutionPolicy Unrestricted -WindowStyle Maximized -File "$(FULL_CURRENT_PATH)"
+%AppData%\Notepad++ # themes/shortcuts.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pwsh -NoExit -ExecutionPolicy Unrestricted -WindowStyle Maximized -File "$(FULL_CURRENT_PATH)"
+
+
+
+
+
+Parsing text to Markdown:
+Macros: Fn<+`+Fn>+Fn>+`+>
+Replace: "# " -> "`"
+
. # Обозначает любой символ
\ # Экранирующий символ. Символы которые экранируются: ^, [, ., $, {, *, (, ), \, +, |, ?, <, >
^ # Начало строки
@@ -260,18 +303,33 @@ $ # Конец строки
\d{2,4} # Найти две или четыре
{4,} # Найти четыре и более
+^\s{0,}#.+
+
# Regex
-replace "1","2" # замена элементов в индексах массива (везде где присутствует 1, заменить на 2), для удаления используется только первое значение
-split " " # преобразовать строку в массив, разделителем указан пробел, которой удаляется ($url.Split("/")[-1])
-join " " # преобразовать массив (коллекцию) в единую строку (string), добавить разделителем пробел
-$iplist -contains "192.168.1.1" # проверить, что в массиве есть целое значение, выводит True или False
-"192.168.1.1" -in $iplist # проверить на наличие указанного значения в массиве
+
-like *txt* # поиск по маскам wildcard, выводит значение на экран
-match txt # поиска по шаблонам, проверка на соответствие содержимого текста
-match "zabbix|rpc" # условия, для поиска по нескольким словам
-NotMatch # проверка на отсутствие вхождения
+### Форматирование (.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 # округлить
+}
+
### Matches
$ip = "192.168.10.1"
$ip -match "(\.\d{1,3})\.\d{1,2}" # True
@@ -283,11 +341,42 @@ $Matches[0][-4..-1] -Join ""
$string.Substring($string.IndexOf(".txt")-4, 4) # 2-й вариант (IndexOf)
-### Группировка
-if ((($1 -eq 1) -and ($2 -eq 2)) -or ($1 -ne 3)) {"$true"} else {"$false"} # два условия: (если $1 = 1 и $2 = 2) или $1 не равно 3. Если хотя бы одно из выражений равно True, то все условие относится к True и наоборот
+### Условный оператор
+$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 # логическое ИЛИ
-!(Test-Path $path) # логическое НЕТ (-not), если путь недоступен, вернет True
+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")
@@ -312,7 +401,6 @@ $ или \Z # обозначают конец строки. $ip -replace "\d{1,3
$test = "string"
$test -replace ".{1}$" # удалить любое кол-во символов в конце строки
$test -replace "^.{1}" # удалить любое кол-во символов в начале строки
-(4164539/1MB).ToString("0.00") # округлить до 3,97
### Группы захвата
$date = '12.31.2021'
@@ -320,24 +408,182 @@ $date -replace '^(\d{2}).(\d{2})','$2.$1' # поменять местами
$1 # содержимое первой группы в скобках
$2 # содержимое второй группы
-### GetType
+# DataType
+
$srv.GetType() # узнать тип данных
$srv -is [string] # проверка на соответствие типа данных
$srv -isnot [System.Object] # проверка на несоответствие
-$char = $srv.ToCharArray() # разбить строку [string] на массив [System.Array] из букв
-$char.GetType() # тип данных: Char[]
[Object] # массив (BaseType:System.Array)
[DateTime] # формат времени (BaseType:System.ValueType)
-[Boolean] # логическое значение ($True/$False)
+[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-разрядное)
-[Char] # cимвол Юникода (16-разрядный)
-[Decimal] # десятичное значение (128-битовое)
-[Byte] # 8-разрядное целое число без знака
-[int16] # 16-разрядное знаковое целое число
-[int] # 32-разрядное знаковое целое число. (BaseType:System.ValueType)
[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] из букв
+
+### 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)
+
### Property
$srv.Count # кол-во элементов в массиве
$srv.Length # содержит количество символом строки переменной [string] или количество значений (строк) объекта
@@ -357,7 +603,9 @@ $int = [convert]::ToInt32($string) # преобразовать строку в
[string]::IsNullOrEmpty($text) # проверяет наличие строки, если строка пуста $true, если нет $false
[string]::IsNullOrWhiteSpace($text2) # проверяет на наличие только символов пробел, табуляция или символ новой строки
-### Date
+### 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]
@@ -366,9 +614,11 @@ $Date = Get-Date -f "dd/MM/yyyy" # получаем тип данных [string]
"5/7/07" -as [DateTime] # преобразовать входные данные в тип данных [DateTime]
New-TimeSpan -Start $VBRRP.CreationTimeUTC -End $VBRRP.CompletionTimeUTC # получить разницу во времени
-### Time
+### 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 # высчитать время работы скрипта
@@ -380,24 +630,6 @@ $timer.IsRunning # статус работы таймера
$timer.Elapsed.TotalSeconds # отобразить время с момента запуска (в секундах)
$timer.Stop() # остановить таймер
-### Условный оператор
-$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 # меньше или равно
-
### Foreach
$list = 100..110 # создать массив из цифр от 100 до 110
foreach ($srv in $list) {ping 192.168.3.$srv -n 1 -w 50} # $srv хранит текущий элемент из $list и повторяет команду до последнего элемента в массиве
@@ -432,7 +664,7 @@ break # остановит цикл
} else {Write-Host "Сайт недоступен"; sleep 1}
}
-### Try
+### Try-Catch-Finally
Try {$out = pping 192.168.3.1}
Catch {Write-Warning "$($error[0])"} # выводит в случае ошибки (вместо ошибки)
@@ -450,8 +682,14 @@ exit 1 # код завершения, который возвращается $L
$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")
-$file.ReadToEnd()
+$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\tloztotk.jpg") # метод открывает двоичный файл, считывает его в массив байт и закрывает файл
+[io.file]::WriteAllBytes("$home\desktop\tloztotk-2.jpg",$file) # сохранить байты в файл (можно использовать для выгрузки двоичных файлов из БД)
Get-Content $home/desktop\test.txt -Wait # аналог tail
Test-Path $path # проверить доступность пути
@@ -693,6 +931,23 @@ cd "C:\Program Files\Windows Defender\"
.\MpCmdRun.exe -restore -name $ThreatName # восстановить файл из карантина
.\MpCmdRun.exe -restore -filepath $path_file
+# 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 ночи
@@ -728,12 +983,14 @@ tnc ya.ru –TraceRoute -Hops 2 # TTL=2
tnc ya.ru -DiagnoseRouting # маршрутизация до хоста, куда (DestinationPrefix: 0.0.0.0/0) через (NextHop: 192.168.1.254)
### nslookup
-nslookup ya.ru 8.8.8.8
-nslookup -type=any ya.ru
+nslookup ya.ru 1.1.1.1 # с указанием DNS сервера
+nslookup -type=any ya.ru # указать тип записи
Resolve-DnsName ya.ru -Type MX # ALL,ANY,A,NS,SRV,CNAME,PTR,TXT(spf)
+[System.Net.Dns]::GetHostEntry("ya.ru")
### route
Get-NetRoute
+New-NetRoute -DestinationPrefix "0.0.0.0/0" -NextHop "192.168.3.1" -InterfaceIndex 8
### ipconfig
Get-NetIPConfiguration
@@ -937,11 +1194,6 @@ Add-WindowsCapability -Online -Name Rsat.CertificateServices.Tools~~~~0.0.1.0
Add-WindowsCapability -Online -Name Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property DisplayName, State # отобразить список установленных компанентов
-### SSH
-Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Client*'
-Add-WindowsCapability -Online -Name OpenSSH.Client*
-dism /Online /Add-Capability /CapabilityName:OpenSSH.Client~~~~0.0.1.0
-
### Import-Module ActiveDirectory
$Session = New-PSSession -ComputerName $srv # -Credential $cred
Export-PSsession -Session $Session -Module ActiveDirectory -OutputModule ActiveDirectory # экспортировать модуль из удаленной сесси (например, с DC)
@@ -1485,7 +1737,52 @@ Get-RSJob | Remove-RSJob
Start-MTPing -Network 192.168.3.0
(Measure-Command {Start-MTPing -Network 192.168.3.0}).TotalSeconds # 10 Seconds
-# PowerCLI
+# Hyper-V
+
+Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart # установить роль на Windows Server
+Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All # установить роль на Windows Desktop
+Get-Command -Module hyper-v
+Get-VMHost
+
+New-VMSwitch -name NAT -SwitchType Internal # создать виртуальный коммутатор и адаптер для него
+Get-NetAdapter | where InterfaceDescription -match Hyper-V # список сетевых адаптеров
+New-NetNat -Name LocalNat -InternalIPInterfaceAddressPrefix "192.168.3.0/24" # задать сеть
+Get-NetAdapter "vEthernet (NAT)" | New-NetIPAddress -IPAddress 192.168.3.200 -AddressFamily IPv4 -PrefixLength 24 # присвоить адрес, необходимо на ВМ указать шлюз 192.168.3.200, что бы находиться за NAT, или в настройка ВМ указать соответствующий адаптер
+Add-NetNatStaticMapping -NatName LocalNat -Protocol TCP -ExternalIPAddress 0.0.0.0 -ExternalPort 2222 -InternalIPAddress 192.168.3.103 -InternalPort 2121 # проброс, вест трафик который приходит на хост Hyper-V TCP/2222, будет перенаправляться на соответствующий порт виртуальной машины за NAT.
+(Get-NetAdapter | where Name -match NAT).Status
+
+Get-NetNatStaticMapping # отобразить пробросы
+Get-NetNat # список сетей
+Remove-NetNatStaticMapping -StaticMappingID 0 # удалить проброс
+Remove-NetNat -Name LocalNat # удалить сеть
+
+New-VMSwitch -Name Local -AllowManagementOS $True -NetAdapterName "Ethernet 4" -SwitchType External # создать вшений (External) виртуальный коммутатор
+$VMName = "hv-dc-01"
+
+$VM = @{
+Name = $VMName
+MemoryStartupBytes = 4Gb
+Generation = 2
+NewVHDPath = "D:\VM\$VMName\$VMName.vhdx"
+NewVHDSizeBytes = 50Gb
+BootDevice = "VHD"
+Path = "D:\VM\$VMName"
+SwitchName = "NAT"
+}
+New-VM @VM
+
+Set-VMDvdDrive -VMName $VMName -Path "C:\Users\Lifailon\Documents\WS-2016.iso"
+New-VHD -Path "D:\VM\$VMName\disk_d.vhdx" -SizeBytes 10GB # создать VHDX диск
+Add-VMHardDiskDrive -VMName $VMName -Path "D:\VM\$VMName\disk_d.vhdx" # примонтировать диск
+Get-VM –VMname $VMName | Set-VM –AutomaticStartAction Start # автозапуск
+Get-VM -Name $VMName | Set-VMMemory -StartupBytes 8Gb
+Set-VMProcessor $VMName -Count 2
+Get-VM -Name $VMName | Checkpoint-VM -SnapshotName "Snapshot-1"
+Restore-VMCheckpoint -Name Snapshot-1" -VMName $VMName -Confirm:$false
+Get-VM | Select -ExpandProperty NetworkAdapters | Select VMName,IPAddresses,Status # получить IP адрес всех ВМ
+vmconnect.exe localhost $VMHost
+
+# VMWare/PowerCLI
Install-Module -Name VMware.PowerCLI # -AllowClobber # установить модуль (PackageProvider: nuget)
Get-Module -ListAvailable VMware* | Select Name,Version
@@ -1559,7 +1856,7 @@ Get-Command –Module *vmware* -name *syslog*
Set-VMHostSysLogServer -VMHost esxi-05 -SysLogServer "tcp://192.168.3.100" -SysLogServerPort 3515
Get-VMHostSysLogServer -VMHost esxi-05
-# EMShell
+# Exchange/EMShell
$srv_cas = "exchange-cas"
$session_exchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$srv_cas/PowerShell/ # -Credential $Cred -Authentication Kerberos
@@ -2776,6 +3073,26 @@ West,Texas,927,923.71
$null,Tennessee,466,770.67
"@
+systeminfo /FO csv | ConvertFrom-Csv # вывод работы программы в CSV и конвертация в объект
+$systeminfo."Полный объем физической памяти"
+$systeminfo."Доступная физическая память"
+
+### ConvertFrom-String
+
+'
+log =
+{
+ level = 4;
+};
+' | ConvertFrom-String # создает PSCustomObject (разбивает по пробелам, удаляет все пробелы и пустые строки)
+
+### ConvertFrom-StringData
+
+"
+key1 = value1
+key2 = value2
+" | ConvertFrom-StringData
+
# XML
$xml = [xml](Get-Content $home\desktop\test.rdg) # прочитать содержимое XML-файла
@@ -2839,16 +3156,6 @@ $xml.Save("$home\desktop\test.xml")
# JSON
-log =
-{
- level = 7;
-};
-
-$log = [xml]"
-
- 7
-"
-
$log = '
{
"log": {
@@ -2859,8 +3166,6 @@ $log = '
Get-Service | ConvertTo-Json
-Invoke-RestMethod https://www.speedtest.net/result/14708271987
-
$OOKLA = '
{
"result" :
@@ -2870,10 +3175,11 @@ $OOKLA = '
}
}
' | ConvertFrom-Json
+$ookla.result
# YAML
-Import-Module PSYaml # используется в Docker-compose и Ansible playbooks
+Import-Module PSYaml # используется в Docker/Ansible
$netplan = "
network: # словарь по типу - ключ : значение с вложенными словарями
ethernets:
@@ -2917,47 +3223,6 @@ New-Chart Column "Top CPU Overall" -input $topCPU
ps | Select ProcessName, Id, CPU, WorkingSet, *MemorySize | New-Table "All Processes"
} > ~\Desktop\Get-Process-HtmlReport.html
-# Git
-
-git --version
-git config --global user.name "Lifailon" # добавить имя для коммитов
-git config --global user.email "lifailon@yandex.ru"
-git config --global --edit
-ssh-keygen -t rsa -b 4096
-Get-Service | where name -match "ssh-agent" | Set-Service -StartupType Automatic
-Get-Service | where name -match "ssh-agent" | Start-Service
-Get-Service | where name -match "ssh-agent" | select Name,Status,StartType
-ssh-agent
-ssh-add C:\Users\Lifailon\.ssh\id_rsa
-cat ~\.ssh\id_rsa.pub | Set-Clipboard # copy to https://github.com/settings/keys
-cd $home\Documents\Git
-git clone git@github.com:Lifailon/PowerShell-Commands
-cd PowerShell-Commands
-git grep powershell # поиск текста в файлах
-git pull # синхронизировать изменения из хранилища
-git status # отобразить статус изменений по файлам
-git diff # отобразить изменения построчно
-git add . # добавить (проиндексировать) изменения во всех файлах
-git commit -m "added file and changed file" # сохранить изменения с комментарием
-git push # синхронизировать локальные изменения с репозиторием
-git branch dev # создать новую ветку
-git switch dev # переключиться на другую ветку
-git push --set-upstream origin dev # добавить ветку
-git branch -d dev # удалить ветку
-git diff rsa # сравнить файлы текущей ветки с файлами в указанной ветки rsa
-git merge dev # слияние текущей ветки (rsa/master) с указанной (dev)
-git log --oneline --all # лог коммитов
-git log --graph # коммиты и следование веток
-git show d01f09dead3a6a8d75dda848162831c58ca0ee13 # отобразить подробный лог по номеру коммита
-git checkout filename # откатить изменения, если не было команды add
-git checkout d01f09dead3a6a8d75dda848162831c58ca0ee13 # переключить локальные файлы рабочей копии на указанный коммит (изменить HEAD на указанный коммит)
-git reset HEAD filename # откатить изменения последнего индекса, если был add но не было commit, тем самым вернуться до последней зафиксированный версии (коммита) и потом выполнить checkout
-git reset --mixed HEAD filename # изменения, содержащиеся в отменяемом коммите, не должны исчезнуть, они будут сохранены в виде локальных изменений в рабочей копии
-git restore filename # отменить все локальные изменения в рабочей копии
-git restore --source d01f09dead3a6a8d75dda848162831c58ca0ee13 filename # восстановить файл на указанную версию по хэшу индентификатора коммита
-git revert HEAD --no-edit # отменить последний коммит, без указания комментария (события записываются в git log)
-git reset --hard d01f09dead3a6a8d75dda848162831c58ca0ee13 # удалить все коммиты до указанного (и откатиться до него)
-
# SQLite
Install-Module MySQLite -Repository PSGallery
@@ -3601,10 +3866,6 @@ DROP USER "admin" # удалить пользователя
### DATABASE
CREATE DATABASE powershell # создать БД
-CREATE DATABASE powershell WITH DURATION 48h REPLICATION 1 NAME "del2d" # создать БД с политикой хранения 2 дня
-CREATE RETENTION POLICY del2h ON powershell DURATION 2h REPLICATION 1 # создать новую политику хранения для БД
-ALTER RETENTION POLICY del2h ON powershell DURATION 2h REPLICATION 1 DEFAULT # изменить (ALTER) политику хранения для БД на DEFAULT
-DROP RETENTION POLICY del2d ON powershell # удаление политики хранения приводит к безвозвратному удалению всех измерений (таблиц) и данных, хранящихся в политике хранения
SHOW DATABASES # отобразить список БД
DROP DATABASE powershell # удалить БД
USE powershell
@@ -3613,14 +3874,21 @@ INSERT performance,host=console,counter=CPU value=0.88 # записать дан
SELECT * FROM performance # отобразить все данные в таблице
SELECT value FROM performance # отфильтровать по столбцу value (только Field Keys)
SELECT * FROM performance limit 10 # отобразить 10 единиц данных
-SELECT * FROM performance WHERE time > now() -1d # отобразить данные за последние 1/4 дня
-SELECT * FROM performance WHERE time > now() +3h -5m # данные за последние 5 минут (+3 часа от текущего времени -5 минут)
+SELECT * FROM performance WHERE time > now() -2d # отобразить данные за последние 2 дня
+SELECT * FROM performance WHERE time > now() +3h -5m # данные за последние 5 минут (+3 часа от текущего времени по UTC 0 -5 минут)
SELECT * FROM performance WHERE counter = 'CPU' # выборка по тэгу
+SELECT upload/1000 FROM speedtest WHERE upload/1000 <= 250 # выборка по столбцу upload и разделить вывод на 1000, вывести upload меньше 250
DELETE FROM performance WHERE time > now() -1h # удалить данные за последние 1/4 часа
DELETE FROM performance WHERE time < now() -24h # удалить данные старше 24 часов
SELECT/DELETE/SHOW/CREATE/DROP/EXPLAIN/GRANT/REVOKE/ALTER/SET/KILL
-SELECT upload/1000 FROM speedtest WHERE upload/1000 <= 250 # отфильтровать по столбцу upload и разделить вывод на 1000, вывести upload меньше 250
+
+### POLICY
+CREATE DATABASE powershell WITH DURATION 48h REPLICATION 1 NAME "del2d" # создать БД с политикой хранения 2 дня
+CREATE RETENTION POLICY del2h ON powershell DURATION 2h REPLICATION 1 # создать новую политику хранения для БД
+CREATE RETENTION POLICY del6h ON powershell DURATION 6h REPLICATION 1 SHARD DURATION 2h # указать период хранения 6 часов + 2 часа до очистки (по умолчанию 1ч или больше)
+ALTER RETENTION POLICY del6h ON powershell DEFAULT # изменить (ALTER) политику хранения для БД на del6h (DEFAULT)
+DROP RETENTION POLICY del2d ON powershell # удаление политики хранения приводит к безвозвратному удалению всех измерений (таблиц) и данных, хранящихся в политике хранения
### API POST
@@ -3639,7 +3907,7 @@ $url = "http://$ipp/write?db=$db"
$user = "admin"
$pass = "password" | ConvertTo-SecureString -AsPlainText -Force
$cred = [System.Management.Automation.PSCredential]::new($user,$pass)
-$unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds
+$unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End ((Get-Date).AddHours(-3))).TotalSeconds # -3h UTC
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
Invoke-RestMethod -Method POST -Uri $url -Body "$table,host=$(hostname) download=200000,upload=300000,ping=3 $timestamp"
@@ -3665,15 +3933,29 @@ $data.results.series.columns # столбцы/ключи
$data.results.series.values # данные построчно
### Endpoint
+https://docs.influxdata.com/influxdb/v1.7/tools/api/
-irm http://localhost:8086/api/v2/setup
-irm http://localhost:8086/api/v2/config
-irm http://localhost:8086/api/v2/write
+$stats = irm http://192.168.3.104:8086/debug/vars # статистика сервера
+$stats."database:powershell".values # кол-во таблиц к БД
+$stats.queryExecutor.values # количество query-запросов (обращений к endpoint /query)
+$stats.write.values # количество write-запросов
+$stats.system.uptime
+
+http://192.168.3.104:8086/debug/requests # кол-во клиентских HTTP-запросов к конечным точкам /writeи /query
+http://192.168.3.104:8086/debug/pprof
+http://192.168.3.104:8086/ping
+http://192.168.3.104:8086/query
+http://192.168.3.104:8086/write
+
+http://192.168.3.99:8086/api/v2/setup
+http://192.168.3.99:8086/api/v2/config
+http://192.168.3.99:8086/api/v2/write
### PingTo-InfluxDB
while ($true) {
- $unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds
+ $tz = (Get-TimeZone).BaseUtcOffset.TotalMinutes
+ $unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End ((Get-Date).AddMinutes(-$tz))).TotalSeconds # -3h UTC
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
$tnc = tnc 8.8.8.8
$Status = $tnc.PingSucceeded
@@ -3705,8 +3987,9 @@ if ($localization -eq 1049) {
$performance = "\Processor(_Total)\% Processor Time"
}
+$tz = (Get-TimeZone).BaseUtcOffset.TotalMinutes
while ($true) {
- $unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds
+ $unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End ((Get-Date).AddMinutes(-$tz))).TotalSeconds # -3h UTC
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
[double]$value = (Get-Counter $performance).CounterSamples.CookedValue.ToString("0.00").replace(",",".") # округлить в тип данных Double
Invoke-RestMethod -Method POST -Uri "http://192.168.3.104:8086/write?db=powershell" -Body "performance,host=$(hostname),counter=CPU value=$value $timestamp"
@@ -3723,23 +4006,22 @@ $Service_Name = "PerformanceTo-InfluxDB"
Get-Service $Service_Name | Start-Service
Get-Service $Service_Name | Set-Service -StartupType Automatic
-### Telegraf
+# Telegraf
Plugins: https://docs.influxdata.com/telegraf/v1.27/plugins/#input-plugins
iwr https://dl.influxdata.com/telegraf/releases/telegraf-1.27.1_windows_amd64.zip -UseBasicParsing -OutFile telegraf-1.27.1_windows_amd64.zip
-Expand-Archive .\telegraf-1.27.1_windows_amd64.zip -DestinationPath "C:\Program Files\InfluxData\telegraf"
-cd "C:\Program Files\InfluxData\telegraf\telegraf-1.27.1"
-.\telegraf.exe --service install --config "C:\Program Files\InfluxData\telegraf\telegraf-1.27.1\telegraf.conf"
-.\telegraf.exe --service uninstall
-.\telegraf.exe -sample-config --input-filter cpu:mem:dns_query --output-filter influxdb > telegraf.conf # создать конфигурацию с выбарнными плагинами для сбора метрик
-.\telegraf.exe --test # тест конфигурации
-ii "C:\Program Files\InfluxData\telegraf\telegraf-1.27.1\telegraf.conf"
+Expand-Archive .\telegraf-1.27.1_windows_amd64.zip -DestinationPath "C:\Telegraf"
+rm telegraf-1.27.1_windows_amd64.zip
+cd C:\Telegraf
+.\telegraf.exe -sample-config --input-filter cpu:mem:dns_query --output-filter influxdb > telegraf_nt.conf # создать конфигурацию с выбарнными плагинами для сбора метрик
+Start-Process notepad++ C:\Telegraf\telegraf_nt.conf
[[outputs.influxdb]]
urls = ["http://192.168.3.104:8086"]
- username = "username"
- password = "userpass"
+ database = "telegraf_nt"
+ username = "user"
+ password = "pass"
[[inputs.cpu]]
percpu = false
totalcpu = true
@@ -3747,12 +4029,15 @@ ii "C:\Program Files\InfluxData\telegraf\telegraf-1.27.1\telegraf.conf"
servers = ["8.8.8.8"]
network = "udp"
domains = ["."]
- ## Possible values: A, AAAA, CNAME, MX, NS, PTR, TXT, SOA, SPF, SRV.
record_type = "A"
port = 53
timeout = "2s"
+.\telegraf.exe --test -config C:\Telegraf\telegraf_nt.conf # тест конфигурации (получения метрик с выводом в консоль)
+C:\Telegraf\telegraf.exe -config C:\Telegraf\telegraf_nt.conf # запустить telegraf (тест отправки данных)
+.\telegraf.exe --config "C:\Telegraf\telegraf_nt.conf" --service install # создать службу
Get-Service telegraf | Start-Service
+.\telegraf.exe --service uninstall
USE telegraf
SELECT usage_idle,usage_system,usage_user FROM cpu
@@ -3877,8 +4162,6 @@ Get-WmiObject -ComputerName localhost -Class Win32_VideoController # отобр
gwmi -List | where name -match "service" | ft -auto # если в таблице присутствуют Methods, то можно взаимодействовать {StartService, StopService}
gwmi -Class win32_service | select * # отобразить список всех служб и всех их свойств
Get-CimInstance Win32_service # обращается на прямую к "root\cimv2"
-Get-CimInstance -ComputerName $srv Win32_OperatingSystem | select LastBootUpTime # время последнего включения
-gwmi -ComputerName $srv -Class Win32_OperatingSystem | select LocalDateTime,LastBootUpTime # текущее время и время последнего включения
gwmi win32_service -Filter "name='Zabbix Agent'" # отфильтровать вывод по имени
(gwmi win32_service -Filter "name='Zabbix Agent'").State # отобразить конкретное свойство
gwmi win32_service -Filter "State = 'Running'" # отфильтровать запущенные службы
@@ -3887,18 +4170,29 @@ gwmi -Query 'select * from win32_service where startmode="Auto"' # WQL-запр
gwmi win32_service | Get-Member -MemberType Method # отобразить все методы взаимодействия с описание применения (Delete, StartService)
(gwmi win32_service -Filter 'name="Zabbix Agent"').Delete() # удалить службу
(gwmi win32_service -Filter 'name="MSSQL$MSSQLE"').StartService() # запустить службу
+
+Get-CimInstance -ComputerName $srv Win32_OperatingSystem | select LastBootUpTime # время последнего включения
+gwmi -ComputerName $srv -Class Win32_OperatingSystem | select LocalDateTime,LastBootUpTime # текущее время и время последнего включения
gwmi Win32_OperatingSystem | Get-Member -MemberType Method # методы reboot и shutdown
(gwmi Win32_OperatingSystem -EnableAllPrivileges).Reboot() # используется с ключем повышения привелегий
(gwmi Win32_OperatingSystem -EnableAllPrivileges).Win32Shutdown(0) # завершение сеанса пользователя
-gwmi -list -Namespace root\CIMV2\Terminalservices
-(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).AllowTSConnections
-(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).SetAllowTSConnections(1) # включить RDP
+
+$system = Get-WmiObject -Class Win32_OperatingSystem
+$InstallDate = [Management.ManagementDateTimeconverter]::ToDateTime($system.installdate) # Получаем дату установки ОС
+$AfterInstallDays = ((Get-Date) — $Installdate).Days # Вычисляем время, прошедшее с момента установки
+$ShortInstallDate = "{0:yyyy-MM-dd HH:MM}" -f ($InstallDate)
+"Система установлена: $ShortInstallDate (Прошло $AfterInstalldays дней)"
+
(Get-WmiObject win32_battery).estimatedChargeRemaining # заряд батареи в процентах
gwmi Win32_UserAccount # доменные пользователи
(gwmi Win32_SystemUsers).PartComponent
Get-CimInstance -ClassName Win32_LogonSession
Get-CimInstance -ClassName Win32_BIOS
+gwmi -list -Namespace root\CIMV2\Terminalservices
+(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).AllowTSConnections
+(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).SetAllowTSConnections(1) # включить RDP
+
$srv = "localhost"
gwmi Win32_logicalDisk -ComputerName $srv | where {$_.Size -ne $null} | select @{
Label="Value"; Expression={$_.DeviceID}}, @{Label="AllSize"; Expression={
@@ -3917,7 +4211,7 @@ REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\P
# Regedit
-Get-PSDrive # список всех доступных дисков и веток реестра
+Get-PSDrive # список всех доступных дисков/разделов, их размер и веток реестра
cd HKLM:\ # HKEY_LOCAL_MACHINE
cd HKCU:\ # HKEY_CURRENT_USER
Get-Item # получить информацию о ветке реестра
@@ -4064,9 +4358,29 @@ $results2 +=[PSCustomObject]@{'ID'=$d.id.ToString();'Data'=$d.Data.ToString()} #
}
$results2
+# OpenSSH
+
+Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Client*'
+Add-WindowsCapability -Online -Name OpenSSH.Client*
+dism /Online /Add-Capability /CapabilityName:OpenSSH.Client~~~~0.0.1.0
+iwr https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.2.2.0p1-Beta/OpenSSH-Win64-v9.2.2.0.msi -OutFile $home\Downloads\OpenSSH-Win64-v9.2.2.0.msi # скачать
+msiexec /i $home\Downloads\OpenSSH-Win64-v9.2.2.0.msi # установить msi пакет
+Set-Service sshd -StartupType Automatic
+Get-NetTCPConnection | where LocalPort -eq 22
+New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
+Get-NetFirewallRule -Name *ssh*
+Start-Process notepad++ C:\Programdata\ssh\sshd_config # конфигурационный файл
+GSSAPIAuthentication yes # включить Kerberos аутентификацию (через AD)
+SyslogFacility LOCAL0 # включить локальное ведение журнала в файл (C:\ProgramData\ssh\logs\sshd.log)
+LogLevel INFO
+Restart-Service sshd
+ssh -K $srv # выполнить Kerberos аутентификацию
+ssh Lifailon@192.168.3.99 -p 22
+pwsh -command Get-Service
+ssh -L 3101:192.168.3.101:22 -R 3101:192.168.3.101:22 lifailon@192.168.3.101 -p 22 # SSH Tunnel lifailon@localhost:3101 -> 192.168.3.101:3101
+
# WinRM
-Get-Service -Name winrm -RequiredServices # статус зависимых служб
Enter-PSSession -ComputerName $srv # подключиться к PowerShell сессии через PSRemoting. Подключение возможно только по FQDN-имени
Invoke-Command $srv -ScriptBlock {Get-ComputerInfo} # выполнение команды через PSRemoting
$session = New-PSSession $srv # открыть сессию
@@ -4074,117 +4388,103 @@ Get-PSSession # отобразить активные сессии
icm -Session $session {$srv = $using:srv} # передать переменную текущей сессии ($using) в удаленную
Disconnect-PSSession $session # закрыть сессию
Remove-PSSession $session # удалить сессию
+Import-Module -Name ActiveDirectory -PSSession $srv # импортировать модуль с удаленного компьютера в локальную сессию
### Windows Remote Management Configuration
+
winrm quickconfig -quiet # изменит запуск службы WinRM на автоматический, задаст стандартные настройки WinRM и добавить исключения для портов в fw
-Enable-PSRemoting –Force
-Test-WSMan $srv -ErrorAction Ignore # проверить работу WinRM на удаленном компьютере (игнорировать вывыод ошибок)
-New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "WinRM HTTPS Certificate" -NotAfter (Get-Date).AddYears(5) # создать самоподписанный сертификат и скопировать отпечаток (thumbprint)
-New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint "CACA491A66D1706AC2FEB5E53D0E111C1C73DD65" # создать прослушиватель
-New-NetFirewallRule -DisplayName 'WinRM HTTPS Management' -Profile Domain,Private -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986 # открыть порт в fw
-winrm enumerate winrm/config/listener # текущая конфигурация прослушивателей WinRM (отображает отпечаток cert SSL для HTTPS 5986)
-dir WSMan:\localhost\client # отобразить конфигурацию
-winrm get winrm/config/service/auth # список всех конфигураций аутентификации WinRM (WSMan:\localhost\client\auth)
-Set-Item -path wsman:\localhost\service\auth\basic -value $true # разрешить локальную аутентификацию
-Set-PSSessionConfiguration -ShowSecurityDescriptorUI -Name Microsoft.PowerShell # добавить права доступа через дескриптор безопасности
-Set-Item WSMan:\localhost\client\allowunencrypted $true # работать без шифрования
-Set-Item WSMan:\localhost\client\TrustedHosts -Value "*" -force # добавить новый доверенный хост (для всех) в конфигурацию
-net localgroup "Remote Management Users" "winrm" /add # добавить пользователя winrm (удалить /del) в локальную группу доступа "пользователи удаленного управления" (Local Groups - Remote Management Users)
+Enable-PSRemoting –Force # включить PowerShell Remoting, работает только для доменного и частного сетевых профилей Windows
+Enable-PSRemoting -SkipNetworkProfileCheck -Force # для настройки компьютера в общей (public) сети (работает с версии powershell 6)
-# Ansible
+$NetProfiles = Get-NetConnectionProfile # отобразить профили сетевых подключений
+Set-NetConnectionProfile -InterfaceIndex $NetProfiles[1].InterfaceIndex -NetworkCategory Private # изменить тип сети для профиля (DomainAuthenticated/Public)
+(Get-CimInstance -ClassName Win32_ComputerSystem).PartOfDomain # проверить, что компьютер добавлен в домен AD
+Get-Service WinRM | Set-Service -StartupType AutomaticDelayedStart # отложенный запуск
+Get-Service -Name winrm -RequiredServices # статус зависимых служб
+New-NetFirewallRule -Profile Any -DisplayName "WinRM HTTP" -Direction Inbound -Protocol TCP -LocalPort 5985,5986
+Test-NetConnection $srv -port 5895 # проверить порт
+Test-WSMan $srv -ErrorAction Ignore # проверить работу WinRM на удаленном компьютере (игнорировать вывод ошибок для скрипта) или локально (localhost)
-apt-get update && apt-get upgrade
-apt-get install ansible
+$Cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "WinRM HTTPS Certificate" -NotAfter (Get-Date).AddYears(5) # создать самоподписанный сертификат
+$Thumbprint = $Cert.Thumbprint # забрать отпечаток
+New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint $Thumbprint -Name WinRM_HTTPS_Listener -Force # создать прослушиватель
+New-NetFirewallRule -DisplayName 'WinRM HTTPS' -Profile Domain,Private -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986 # открыть порт в fw
-nano /etc/ansible/ansible.cfg # файл конфигурации
-#inventory = /etc/ansible/hosts
+$selector_set = @{
+ Address = "*"
+ Transport = "HTTPS"
+}
+$value_set = @{
+ CertificateThumbprint = "66ABFDA044D8C85135048186E2FDC0DBE6125163"
+}
+New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set
-nano /etc/ansible/hosts
+winrm get winrm/config # отобразить всю конфигурацию (Client/Service)
+winrm get winrm/config/service/auth # конфигурация авторизации на сервере
+winrm enumerate winrm/config/listener # текущая конфигурация прослушивателей WinRM (отображает отпечаток сертификата для HTTPS 5986)
+Get-ChildItem -Path Cert:\LocalMachine\My\ | where Thumbprint -eq D9356FB774EE0E6206B7D5B59B99102CA5B17BDA | select * # информация о сертификате
-[elk]
-devlog-01.domain.local ansible_host=192.168.11.230
-netbox-01.domain.local ansible_host=192.168.11.245
+ls WSMan:\localhost\Client # конфигурацию клиента
+ls WSMan:\localhost\Service # конфигурация сервера
+ls WSMan:\localhost\Service\auth # список всех конфигураций аутентификации WinRM сервера
+Set-Item -path WSMan:\localhost\Service\auth\basic -value $true # разрешить локальную аутентификацию к текущему серверу
+ls HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN # настройки в реестре (например, для включения аудентификации в \Service\auth_basic = 1)
+Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.* -Force # добавить доверенные хосты в конфигурацию на клиенте, чтобы работала Negotiate аутентификация через NTLM
+Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.3.100 -Concatenate -Force # добавить второй компьютер
+ls WSMan:\localhost\Client\TrustedHosts
+Set-Item WSMan:\localhost\Client\AllowUnencrypted $true # включить передача незашифрованных данных конфигурации клиента
+Set-Item WSMan:\localhost\Service\AllowUnencrypted $true # включить передача незашифрованных данных конфигурации сервера (необходимо быть в private сети)
-[all:vars]
-path_user=/home/us
-ansible_user=us
-ansible_ssh_port=22
+Get-PSSessionConfiguration # проверить, включен ли PSremoting и вывести список пользователей и групп, которым разрешено подключаться через WinRM
+Set-PSSessionConfiguration -Name Microsoft.PowerShell -ShowSecurityDescriptorUI # назначить права доступа через дескриптор безопасности текущей сессии (до перезагруки)
+(Get-PSSessionConfiguration -Name "Microsoft.PowerShell").SecurityDescriptorSDDL # получить настройки дескриптора в формате SDDL
+Set-PSSessionConfiguration -Name Microsoft.PowerShell -SecurityDescriptorSDDL $SDDL # применить настройки дескриптора на другом компьютере без использования GUI
-[ws_vproxy]
-vproxy-01 ansible_host=192.168.11.196
-vproxy-03 ansible_host=192.168.11.188
-vproxy-04 ansible_host=192.168.11.64
+New-LocalUser "WinRM-Writer" -Password (ConvertTo-SecureString -AsPlainText "123098") # создать пользователя
+Add-LocalGroupMember -Group "Remote Management Users" -Member "WinRM-Writer" # добавить пользователя WinRM-Writer в локальную группу доступа "Пользователи удаленного управления"
+cmdkey /add:192.168.3.99 /user:WinRM-Writer /pass:123098 # сохранить пароль в CredentialManager
+cmdkey /list
+Import-Module CredentialManager
+Add-Type -AssemblyName System.Web
+New-StoredCredential -Target 192.168.3.99 -UserName WinRM-Writer -Password 123098 -Comment WinRM # сохранить пароль в CredentialManager (из PS5)
+Get-StoredCredential -AsCredentialObject
+$cred = Get-StoredCredential -Target 192.168.3.99
+Enter-PSSession -ComputerName 192.168.3.99 -Credential $cred -Authentication Negotiate
+Enter-PSSession -ComputerName 192.168.3.99 -Credential $cred -Authentication Basic -Port 5985 # работает при отключении allowunencrypted на стороне сервера и клиента
+winrs -r:http://192.168.3.100:5985/wsman -u:WinRM-Writer -p:123098 ipconfig # передать команду через winrs (-?)
+winrs -r:https://192.168.3.100:5985/wsman -u:WinRM-Writer -p:123098 -ssl ipconfig # через https
+pwsh -Command "Install-Module -Name PSWSMan" # установить модуль для использования в Linux системе
-[ws_vproxy:vars]
-ansible_user=winrm
-#ansible_user=support4@DOMAIN.LOCAL
-ansible_password=123098
-ansible_port=5986
-ansible_connection=winrm
-ansible_winrm_transport=basic
-#ansible_winrm_transport=kerberos
-ansible_winrm_server_cert_validation=ignore
-validate_certs=false
+### Kerberos
-ansible-inventory --list -y
+.\CheckMaxTokenSize.ps1 -Principals login -OSEmulation $true -Details $true # узнать размер токена пользователя в домене
+Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters | select maxtokensize # максимальный размер токена на сервере
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters # изменить размера, если заголовок пакета аутентификации превышает 16 Кб (из за большого кол-ва групп)
+MaxFieldLength увеличить до 0000ffff (65535)
+MaxRequestBytes увеличить до 0000ffff (65535)
-### Modules
+# pki
-ansible-doc -l | grep windows # оф. документация модулей
-ansible elk -m ping
-#ansible all -m ping -u us
-ansible all -m shell -a "lsblk " -vvvvv # debug выполнения команды, чем больше "v" тем больше отображение
-ansible elk -m setup | grep -iP "mem|proc" # информация о железе
-ansible elk -m apt -a "name=mc"
-ansible elk -m service -a "name=ssh state=restarted enabled=yes" -b # перезапустить службу
-# -b - повысить привилегии (sudo)
+Get-ChildItem -Path Cert:\CurrentUser\Root\ # список всех установленных сертификатов в хранилище Доверенные корневые ЦС Текущего пользователя
+Get-ChildItem -Path Cert:\CurrentUser\My\ # список самозаверяющих сертификатов в Личное хранилище Текущего пользователя
+Get-ChildItem -Path Cert:\LocalMachine\My\ # список самозаверяющих сертификатов в Личное хранилище Локального компьютера
+Get-ChildItem -Path Cert:\LocalMachine\My\ | select NotBefore,NotAfter,Thumbprint,Subject # срок действия сертификата
+Get-ChildItem -Path Cert:\LocalMachine\My\ | where Thumbprint -eq D9356FB774EE0E6206B7D5B59B99102CA5B17BDA # поиск сертификат по отпечатку
-### Copy
+Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Certificates\ # сертификаты в файловой системе, каждый файл соответствует сертификату, установленному в личном хранилище текущего пользователя
+Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Keys\ # ссылки на объекты закрытых ключей, созданных поставщиком хранилища ключей (KSP)
+Get-ChildItem -Path HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates | ft -AutoSize # список сертификатов в реестре вошедшего в систему пользователя
-echo "21" > test.txt
-ansible elk -m copy -a "src=test.txt dest=/root mode=777" -b
-ansible elk -a "ls /root" -b
-ansible elk -a "cat /root/test.txt" -b
+$cert = (Get-ChildItem -Path Cert:\CurrentUser\My\)[1] # выбрать сертификат
+$cert | Remove-Item # удалить сертификат
-### Args
+Export-Certificate -FilePath $home\Desktop\certificate.cer -Cert $cert # экспортировать сертификат
+$cert.HasPrivateKey # проверить наличие закрытого ключа
+$pass = "password" | ConvertTo-SecureString -AsPlainText -Force # создать пароль для шифрования закрытого ключа
+Export-PfxCertificate -FilePath $home\Desktop\certificate.pfx -Password $pass -Cert $certificate # экспортировать сертификат с закрытым ключем
-ansible elk -m shell -a "uptime"
-ansible elk -a "mkdir /home/us/test"
-ansible elk -a "ls $path_user"
-
-### Windows Modules
-
-ansible ws_vproxy -m win_ping
-ansible ws_vproxy -m raw -a "ipconfig"
-ansible ws_vproxy -m win_shell -a "Get-Service | select name,status"
-ansible ws_vproxy -m win_service -a "name=Spooler state=started"
-
-### Playbook
-
-nano /etc/ansible/elk.yml
-
-- hosts: elk
- become: yes
- tasks:
- - name: Create group tester
- action: group name=tester state=present
- - name: Add user to system
- user: name=tester shell=/bin/bash groups=tester append=yes
-
-ansible-playbook /etc/ansible/elk.yml # -i /etc/ansible/hosts
-
-### Обновить и установить пакет
-
-- hosts: all
- become: yes
- tasks:
- - name: Run apt-get update
- apt:
- update_cache: yes
- - name: Install latest version nmap
- apt:
- name: nmap
- state: latest
+Import-Certificate -FilePath $home\Desktop\certificate.cer -CertStoreLocation Cert:\CurrentUser\My # импортировать сертификат
+Import-PfxCertificate -Exportable -Password $pass -CertStoreLocation Cert:\CurrentUser\My -FilePath $home\Desktop\certificate.pfx
# DSC
@@ -4248,3 +4548,370 @@ $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
+
+# Git
+
+git --version
+git config --global user.name "Lifailon" # добавить имя для коммитов
+git config --global user.email "lifailon@yandex.ru"
+git config --global --edit
+ssh-keygen -t rsa -b 4096
+Get-Service | where name -match "ssh-agent" | Set-Service -StartupType Automatic
+Get-Service | where name -match "ssh-agent" | Start-Service
+Get-Service | where name -match "ssh-agent" | select Name,Status,StartType
+ssh-agent
+ssh-add C:\Users\Lifailon\.ssh\id_rsa
+cat ~\.ssh\id_rsa.pub | Set-Clipboard # copy to https://github.com/settings/keys
+cd $home\Documents\Git
+git clone git@github.com:Lifailon/PowerShell-Commands
+cd PowerShell-Commands
+git grep powershell # поиск текста в файлах
+git pull # синхронизировать изменения из хранилища
+git status # отобразить статус изменений по файлам
+git diff # отобразить изменения построчно
+git add . # добавить (проиндексировать) изменения во всех файлах
+git commit -m "added file and changed file" # сохранить изменения с комментарием
+git push # синхронизировать локальные изменения с репозиторием
+git branch dev # создать новую ветку
+git switch dev # переключиться на другую ветку
+git push --set-upstream origin dev # добавить ветку
+git branch -d dev # удалить ветку
+git diff rsa # сравнить файлы текущей ветки с файлами в указанной ветки rsa
+git merge dev # слияние текущей ветки (rsa/master) с указанной (dev)
+git log --oneline --all # лог коммитов
+git log --graph # коммиты и следование веток
+git show d01f09dead3a6a8d75dda848162831c58ca0ee13 # отобразить подробный лог по номеру коммита
+git checkout filename # откатить изменения, если не было команды add
+git checkout d01f09dead3a6a8d75dda848162831c58ca0ee13 # переключить локальные файлы рабочей копии на указанный коммит (изменить HEAD на указанный коммит)
+git reset HEAD filename # откатить изменения последнего индекса, если был add но не было commit, тем самым вернуться до последней зафиксированный версии (коммита) и потом выполнить checkout
+git reset --mixed HEAD filename # изменения, содержащиеся в отменяемом коммите, не должны исчезнуть, они будут сохранены в виде локальных изменений в рабочей копии
+git restore filename # отменить все локальные изменения в рабочей копии
+git restore --source d01f09dead3a6a8d75dda848162831c58ca0ee13 filename # восстановить файл на указанную версию по хэшу индентификатора коммита
+git revert HEAD --no-edit # отменить последний коммит, без указания комментария (события записываются в git log)
+git reset --hard d01f09dead3a6a8d75dda848162831c58ca0ee13 # удалить все коммиты до указанного (и откатиться до него)
+
+# Ansible
+
+apt -y update && apt -y upgrade
+apt -y install ansible # v2.10.8
+apt -y install ansible-core # v2.12.0
+apt -y install sshpass
+
+ansible-galaxy collection install ansible.windows # установить коллекцию модулей
+ansible-galaxy collection install community.windows
+ansible-galaxy collection list | grep windows
+ansible-config dump | grep DEFAULT_MODULE_PATH # путь хранения модулей
+
+apt-get -y install python-dev libkrb5-dev krb5-user # пакеты для Kerberos аутентификации
+apt install python3-pip
+pip3 install requests-kerberos
+nano /etc/krb5.conf # настроить [realms] и [domain_realm]
+kinit -C support4@domail.local
+klist
+
+ansible --version
+config file = None
+nano /etc/ansible/ansible.cfg # файл конфигурации
+
+[defaults]
+inventory = /etc/ansible/hosts
+# uncomment this to disable SSH key host checking
+# Отключить проверку ключа ssh (для подключения используя пароль)
+host_key_checking = False
+
+nano /etc/ansible/hosts
+
+[us]
+pi-hole-01 ansible_host=192.168.3.101
+zabbix-01 ansible_host=192.168.3.102
+grafana-01 ansible_host=192.168.3.103
+netbox-01 ansible_host=192.168.3.104
+
+[all:vars]
+ansible_ssh_port=2121
+ansible_user=lifailon
+ansible_password=123098
+path_user=/home/lifailon
+ansible_python_interpreter=/usr/bin/python3
+
+[ws]
+huawei-01 ansible_host=192.168.3.99
+plex-01 ansible_host=192.168.3.100
+
+[ws:vars]
+ansible_port=5985
+#ansible_port=5986
+ansible_user=Lifailon
+#ansible_user=support4@DOMAIN.LOCAL
+ansible_password=123098
+ansible_connection=winrm
+ansible_winrm_scheme=http
+ansible_winrm_transport=basic
+#ansible_winrm_transport=kerberos
+ansible_winrm_server_cert_validation=ignore
+validate_certs=false
+
+[win_ssh]
+huawei-01 ansible_host=192.168.3.99
+plex-01 ansible_host=192.168.3.100
+
+[win_ssh:vars]
+ansible_python_interpreter=C:\Users\Lifailon\AppData\Local\Programs\Python\Python311\ # добавить переменную среды интерпритатора Python в Windows
+ansible_connection=ssh
+#ansible_shell_type=cmd
+ansible_shell_type=powershell
+
+ansible-inventory --list # проверить конфигурацию (читает в формате JSON) или YAML (-y) с просмотром все применяемых переменных
+
+# Modules
+
+ansible us -m ping
+ansible win_ssh -m ping
+ansible us -m shell -a "uptime && df -h | grep lv"
+ansible us -m setup | grep -iP "mem|proc" # информация о железе
+ansible us -m apt -a "name=mc" -b # повысить привилегии sudo (-b)
+ansible us -m service -a "name=ssh state=restarted enabled=yes" -b # перезапустить службу
+echo "echo test" > test.sh
+ansible us -m copy -a "src=test.sh dest=/root mode=777" -b
+ansible us -a "ls /root" -b
+ansible us -a "cat /root/test.sh" -b
+
+ansible-doc -l | grep win_ # список всех модулей Windows (https://docs.ansible.com/ansible/latest/collections/ansible/windows/)
+ansible ws -m win_ping # windows модуль
+ansible ws -m win_ping -u WinRM-Writer # указать логин
+ansible ws -m win_shell -a '$PSVersionTable'
+ansible ws -m win_shell -a 'Get-Service | where name -match "ssh|winrm"'
+ansible ws -m win_service -a "name=sshd state=stopped"
+ansible ws -m win_service -a "name=sshd state=started"
+
+### win_shell
+
+nano /etc/ansible/Get-PowerShell.yml
+
+- hosts: ws
+ # Указать коллекцию модулей
+ collections:
+ - ansible.windows
+ tasks:
+ - name: Get port ssh
+ win_shell: |
+ Get-Content "C:\Programdata\ssh\sshd_config" | Select-String "port\s"
+ # Зарегистрировать вывод в переменную
+ register: command_output
+ - name: Output port ssh
+ # Вывести переменную на экран
+ debug:
+ var: command_output.stdout_lines
+
+ansible-playbook /etc/ansible/Get-PowerShell.yml
+
+### win_powershell
+
+nano /etc/ansible/powershell-param.yml
+
+- hosts: ws
+ tasks:
+ - name: Run PowerShell script with parameters
+ ansible.windows.win_powershell:
+ parameters:
+ Path: C:\Temp
+ Force: true
+ script: |
+ [CmdletBinding()]
+ param (
+ [String]$Path,
+ [Switch]$Force
+ )
+ New-Item -Path $Path -ItemType Directory -Force:$Force
+
+ansible-playbook /etc/ansible/powershell-param.yml
+
+### win_chocolatey
+
+nano /etc/ansible/setup-chocolatey.yml
+
+- hosts: ws
+ tasks:
+ - name: Install Acrobat Reader
+ win_chocolatey:
+ name: adobereader
+ state: present
+
+ansible-playbook /etc/ansible/setup-chocolatey.yml
+
+nano /etc/ansible/setup-chocolatey.yml
+
+- hosts: ws
+ tasks:
+ - name: install the Win32-OpenSSH service
+ win_chocolatey:
+ name: openssh
+ package_params: /SSHServerFeature
+ state: present
+
+ansible-playbook /etc/ansible/setup-chocolatey.yml
+
+### win_regedit
+
+nano /etc/ansible/win-set-shell-ssh-ps7.yml
+
+- hosts: ws
+ tasks:
+ - name: Set the default shell to PowerShell 7 for Windows OpenSSH
+ win_regedit:
+ path: HKLM:\SOFTWARE\OpenSSH
+ name: DefaultShell
+ # data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
+ data: 'C:\Program Files\PowerShell\7\pwsh.exe'
+ type: string
+ state: present
+
+ansible-playbook /etc/ansible/win-set-shell-ssh-ps7.yml -i /etc/ansible/hosts
+
+### win_copy
+
+echo "Get-Service | where name -eq vss | Start-Service" > /home/lifailon/Start-Service-VSS.ps1
+nano /etc/ansible/copy-file-to-win.yml
+
+- hosts: ws
+ tasks:
+ - name: Copy file to win hosts
+ win_copy:
+ src: /home/lifailon/Start-Service-VSS.ps1
+ dest: C:\Users\Lifailon\Desktop\Start-Service-VSS.ps1
+
+ansible-playbook /etc/ansible/copy-file-to-win.yml
+
+curl -OL https://github.com/PowerShell/PowerShell/releases/download/v7.3.6/PowerShell-7.3.6-win-x64.msi
+nano /etc/ansible/copy-file-to-win.yml
+
+- hosts: ws
+ tasks:
+ - name: Copy file to win hosts
+ win_copy:
+ src: /home/lifailon/PowerShell-7.3.6-win-x64.msi
+ dest: C:\Install\PowerShell-7.3.6.msi
+
+ansible-playbook /etc/ansible/copy-file-to-win.yml
+
+### win_command
+
+nano /etc/ansible/run-script-ps1.yml
+
+- hosts: ws
+ tasks:
+ - name: Run PowerShell Script
+ win_command: powershell -ExecutionPolicy ByPass -File C:\Users\Lifailon\Desktop\Start-Service-VSS.ps1
+
+ansible-playbook /etc/ansible/run-script-ps1.yml
+
+### win_package
+
+nano /etc/ansible/setup-msi-package.yml
+
+- hosts: ws
+ tasks:
+ - name: Install MSI Package
+ win_package:
+# path: C:\Install\7z-23.01.msi
+ path: C:\Install\PowerShell-7.3.6.msi
+ arguments:
+ - /quiet
+ - /passive
+ - /norestart
+
+ansible-playbook /etc/ansible/setup-msi-package.yml
+
+### win_firewall_rule
+
+nano /etc/ansible/win-fw-open.yml
+
+- hosts: ws
+ tasks:
+ - name: Open RDP port
+ win_firewall_rule:
+ name: Open RDP port
+ localport: 3389
+ action: allow
+ direction: in
+ protocol: tcp
+ state: present
+ enabled: yes
+
+ansible-playbook /etc/ansible/win-fw-open.yml
+
+### win_group
+
+nano /etc/ansible/win-creat-group.yml
+
+- hosts: ws
+ tasks:
+ - name: Create a new group
+ win_group:
+ name: deploy
+ description: Deploy Group
+ state: present
+
+ansible-playbook /etc/ansible/win-creat-group.yml
+
+### win_group_membership
+
+nano /etc/ansible/add-user-to-group.yml
+
+- hosts: ws
+ tasks:
+ - name: Add a local and domain user to a local group
+ win_group_membership:
+ name: deploy
+ members:
+ - WinRM-Writer
+ state: present
+
+ansible-playbook /etc/ansible/add-user-to-group.yml
+
+### win_feature
+
+nano /etc/ansible/install-feature.yml
+
+- hosts: ws
+ tasks:
+ - name: Install Windows Feature
+ win_feature:
+ name: SNMP-Service
+ state: present
+
+ansible-playbook /etc/ansible/install-feature.yml
+
+### win_reboot
+
+nano /etc/ansible/win-reboot.yml
+
+- hosts: ws
+ tasks:
+ - name: Reboot a slow machine that might have lots of updates to apply
+ win_reboot:
+ reboot_timeout: 3600
+
+ansible-playbook /etc/ansible/win-reboot.yml
+
+# Jenkins
+
+nano /etc/apt/sources.list.d/jenkins.list
+deb [trusted=yes] https://pkg.jenkins.io/debian binary/
+apt-get update
+apt-get install -y fontconfig openjdk-11-jre
+apt-get install -y jenkins
+systemctl status jenkins
+cat /var/lib/jenkins/secrets/initialAdminPassword
+
+Item - Pipeline
+SCM - Git
+Repository URL: https://github.com/Lifailon/Deploy-PS-Module.git
+Branch: */rsa
+Script Path: Pipeline/jenkinsfile.groovy
+
+Item - Freestyle
+This build is parameterized - Add Parameter - String Parameter - Process_Name
+Add build step - PowerShell
+Command:
+pwsh -command Get-Process -name *$env:Process_Name*
\ No newline at end of file