Powershell
Docker
docker run -it --rm -e POWERSHELL_TELEMETRY_OPTOUT=1 mcr.microsoft.com/powershell
docker run -it --rm -e POWERSHELL_TELEMETRY_OPTOUT=1 mcr.microsoft.com/azure-powershell
Политики запуска
Restricted (Ограниченный) - Значение по умолчанию. Блокируется выполнение любых скриптов и разрешается работа интерактивных команд.
AllSigned (Все подписанные) - Разрешено выполнение скриптов, имеющих цифровую подпись.
RemoteSigned (Удаленные подписанные) - Локальные скрипты работают без подписи. Все скачанные скрипты должны иметь цифровую подпись.
Unrestricted (Неограниченный) - Разрешено выполнение любых скриптов. При запуске не подписанного скрипта, который был загружен из Интернета, программа может потребовать подтверждение.
Bypass (Обходной) - Ничего не блокируется, никакие предупреждения и запросы не появляются.
Показать текущую политику:
Get-ExecutionPolicy
Установить политику RemoteSigned:
Set-ExecutionPolicy RemoteSigned
Переменные
Кавычки и экранирование
Операторы сравнения
| Оператор | Значение |
| -eq | равно |
| -ne | не равно |
| -lt | меньше |
| -le | меньше или равно |
| -gt | больше |
| -ge | больше или равно |
| -like | сравнение строки |
| -clike | регистронезависимое сравнение строки |
| -notlike | сравнение на несовпадение строки |
| -contains | содержит |
| -notcontains | не содержит |
| -match | сравнение с регулярным выражением |
| -cmatch | регистронезависимое сравнение с регулярным выражением |
Для регистрозависимого сравнения до бавляем c, например -сeq, -сlike
Операторы сравнения могут быть соединены с помощью логических операторов:
| Оператор | Значение |
| -and | И |
| -or | ИЛИ |
| -not | НЕ |
| ! | НЕ |
Работа с файлами
Move-Item - Перемещение файлов
Copy-Item - Копирование файлов
Показать список расширений файлов в директории рекурсивно:
Get-ChildItem 'F:\DatasetScans' -File -Recurse | Select Extension | Sort-Object -Unique
Управление реестром
Список доступных дисков:
get-psdrive
Перейти к ветке реестра и показать содержимое:
Set-Location -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching
Get-ChildItem
или одной командой:
Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching
Пересоздать раздел:
New-Item –Path HKCU: –Name Test1\Test2 -Force
Перезаписать значение ветки:
Set-ItemProperty -Path "HKCU:\Test1\Test2" -Name "NameTest" -Value 0 -PropertyType "dword" -Force
Удалить значение ветки:
Remove-ItemProperty –Path HKCU:\Test1\Test2 –Name NameTest
Удалить все ветки в разделе:
Remove-Item –Path HKCU:\Test1\* –Recurse
Удалить ветку в разделе:
Remove-Item –Path HKCU:\Test1 –Recurse
http://winitpro.ru/index.php/2017/02/07/rabotaem-s-reestrom-windows-cherez-powershell/
Тест подключения
Проверить подключение на 443 порту хоста ya.ru
Test-NetConnection -ComputerName ya.ru -Port 443
Ошибки
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
Выполняем скрипт с повышенными привилегиями:
powershell.exe -executionpolicy remotesigned .\example.ps1
http://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html
+ CategoryInfo : NotSpecified: (:) [Get-WindowsFeature], KeyNotFoundException
+ FullyQualifiedErrorId : System.Collections.Generic.KeyNotFoundException,Microsoft.Windows.ServerManager.Commands
или
The given key was not present in the dictionary
Проблема с кэшем. Удаляем ключ реестра с повышенными привилегиями:
reg delete HKLM\SOFTWARE\Microsoft\ServerManager\ServicingStorage\ServerComponentCache
https://www.saqwel.ru/articles/windows/the-given-key-was-not-present-in-the-dictionary/
PackageManagement\Install-Package : No match was found for the specified search criteria and module name
Не зарегистрирован репозиторий. Зарегистрировать:
$parameters = @{
Name = "PSGallery"
SourceLocation = "https://www.powershellgallery.com/api/v2"
PublishLocation = "https://www.powershellgallery.com/api/v2/package/"
ScriptSourceLocation = "https://www.powershellgallery.com/api/v2/items/psscript"
ScriptPublishLocation = "https://www.powershellgallery.com/api/v2/package/"
InstallationPolicy = 'Untrusted'
}
Register-PSRepository @parameters
Exception calling «SqlRestore» with «1» argument(s): «Restore failed for Server 'SERVER'.»
Проблема с таймаутом, по умолчанию 600 сек. Увеличить таймаут до 30мин:
$serverInstance = New-Object ('Microsoft.SqlServer.Management.Smo.Server') "$INSTANCE"
$serverInstance.ConnectionContext.StatementTimeout = 1800
Примеры
Посмотреть все свойства объекта: … | Select-Object -ExpandProperty properties | Select Name,Value | Sort -Property Name
| Powershell | Bash | Описание |
| >$null | >/dev/null | Перенаправление вывода |
(Get-Location).Path
(Get-Item . -Force).FullName | pwd | Текущая директория |
| Get-ChildItem -Path ${DIRECTORY} -Force | %{ $_.FullName } | find ${DIRECTORY} -maxdepth 1 | Список файлов в директории |
Однострочник
| powershell | winbatch |
echo "Hello!" ; if ($?) { echo "World!" }
| echo "Hello!" && echo "World!"
|
echo "Hello!" ; if (-not $?) { echo "Bye!" }
| echo "Hello!" || echo "Bye!"
|
Отображение команд
| powershell | bash |
Set-PSDebug -Trace 1; ls; Set-PSDebug -Trace 0
| set -x; ls; set +x
|
Сравнение
| powershell | bash |
Compare-Object -ReferenceObject (Get-Content -Path 1.txt)
-DifferenceObject (Get-Content -Path2.txt)
| diff 1.txt 2.txt
|
Назначение переменных
Пример назначения переменных с использованием других переменных:
for ($i=1; $i -le 5; $i++)
{
New-Variable -Name "var$i" -Value $i
Get-Variable -Name "var$i" -ValueOnly
}
Создание файла
Вывести на экран файл
Вывести без комментариев
Добавить:
| Select-String "^\s*#|^\s*$" -NotMatch | % { $_.Line }
Param
AD
Получить список групп пользователя:
https://sergeyvasin.net/2017/09/18/primary-group/
Получить список пользователей группы (пример группы ofdrole с выводом только логина, без заголовков):
Get-ADGroupMember 'ofdrole' | select samaccountname | ft -hide
Скопировать пользователей из одной группы в другую:
Add-ADGroupMember -Identity '${NEWGROUP}' -Members (Get-ADGroupMember -Identity '${OLDGROUP}')
ФС
Вывести размер директорий:
gci -force 'C:\Users'-ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | % {
$len = 0
gci -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length }
$_.fullname, '{0:N2} GB' -f ($len / 1Gb)
}
Proccess
Вывести список процессов «OCR.Worker.JustICR», с используемой ими памятью (более 500MB) и pid:
Get-Process | Where-Object {$_.ProcessName -match "OCR.Worker.JustICR" -and $_.WS -gt 524288000 } | Select-Object ProcessName,WS,Id
Остановить процессы «OCR.Worker.JustICR» занимающее более 500MB памяти:
Get-Process | Where-Object {$_.ProcessName -match "OCR.Worker.JustICR" -and $_.WS -gt 524288000 } | Stop-Process -Force
Показать UserName и использование памяти процессов w3wp:
Get-Process -IncludeUserName -Name w3wp | Select-Object UserName,WS
Certificates
Создать самоподписанный сертификат в хранилище Cert:\LocalMachine\my
Создать самоподписанный сертификат в хранилище Cert:\LocalMachine\my
$params = @{
Type = 'Custom'
Subject = 'SelfSignedCertificate'
TextExtension = @('2.5.29.17={text}DNS=localhost&IPAddress=127.0.0.1&IPAddress=::1')
HashAlgorithm = 'SHA256'
KeyAlgorithm = 'RSA'
KeyLength = 2048
KeyUsage = 'DigitalSignature'
CertStoreLocation = 'Cert:\LocalMachine\My'
NotAfter = (Get-Date).AddYears(10)
}
$Thumbprint = New-SelfSignedCertificate @params | Select -ExpandProperty Thumbprint
Экспортировать сертификат из хранилища Cert:\LocalMachine\my в Apps.pfx
Экспортировать сертификат из хранилища Cert:\LocalMachine\my в Apps.pfx
$pfxpwd = ConvertTo-SecureString -String '2003' -Force -AsPlainText
Get-ChildItem -Path Cert:\LocalMachine\My\$Thumbprint | Export-PfxCertificate -FilePath Apps.pfx -Password $pfxpwd
Импортировать сертификат из Apps.pfx в хранилище Cert:\LocalMachine\My и Cert:\LocalMachine\Root, задать пароль для pfx во всплывающем окне
Импортировать сертификат из Apps.pfx в хранилище Cert:\LocalMachine\My и Cert:\LocalMachine\Root, задать пароль для pfx во всплывающем окне
$pfxpwd = Get-Credential -UserName 'Enter password below' -Message 'Enter password below'
Import-PfxCertificate -FilePath Apps.pfx -CertStoreLocation Cert:\LocalMachine\My -Exportable -Password $pfxpwd.Password | Select -ExpandProperty Thumbprint
Import-PfxCertificate -FilePath Apps.pfx -CertStoreLocation Cert:\LocalMachine\Root -Exportable -Password $pfxpwd
Показать список сертификатов:
dir Cert:\LocalMachine\my
Поменять разрешения на сертификат
Поменять разрешения на сертификат
$Thumbprint=<set Thumbprint>
$fileCert = ([System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($(Get-ChildItem Cert:\LocalMachine\My | Where thumbprint -eq $Thumbprint))).key.UniqueName
if (Test-Path "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\MachineKeys\$fileCert"){
$certPath = "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\MachineKeys\$fileCert"
} elseif (Test-Path "C:\ProgramData\Microsoft\Crypto\Keys\$fileCert"){
$certPath = "$env:ALLUSERSPROFILE\Microsoft\Crypto\Keys\$fileCert"
} elseif (Test-Path "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\$fileCert"){
$certPath = "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\$fileCert"
}
$permissions = Get-Acl -Path "$certPath"
$acl = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", 'Read', 'None', 'None', 'Allow')
$permissions.AddAccessRule($acl)
Set-Acl -Path $certPath -AclObject $permissions
Zip
Показать список файлов:
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
[IO.Compression.ZipFile]::OpenRead("$zipFile").Entries.FullName
Показать файл в архиве (пример для файла «appsettings.Standalone.json»):
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
[System.IO.StreamReader]::new([IO.Compression.ZipFile]::OpenRead("$zipFile").GetEntry("appsettings.Standalone.json").Open()).ReadToEnd()
Извлечь файл из архива (пример для файла «appsettings.Standalone.json»):
Add-Type -AssemblyName System.IO.Compression, System.IO.Compression.FileSystem
$zip = New-Object IO.Compression.ZipArchive((New-Object IO.FileStream("$zipFile", [IO.FileMode]::Open)), [IO.Compression.ZipArchiveMode]::Read)
$zip.Entries | Where-Object Name -like "appsettings.Standalone.json" | ForEach-Object{[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "appsettings.Standalone.json", $true)}
$zip.Dispose()
Удалить файлы в архиве (пример для файлов «appsettings*.json»):
Add-Type -AssemblyName System.IO.Compression, System.IO.Compression.FileSystem
$zip = New-Object IO.Compression.ZipArchive((New-Object IO.FileStream("$zipFile", [IO.FileMode]::Open)), [IO.Compression.ZipArchiveMode]::Update)
($zip.Entries | ? { $_.Name -like "appsettings*.json" }) | % { $_.Delete() }
$zip.Dispose()
Добавить файл в архив (пример для файла «appsettings.json»):
Compress-Archive -Update "appsettings.json" "$zipFile"
Форматирование текста
Модули
Install-Module -Name <Name> #Установить модуль
Uninstall-Module -Name <Name> #Удалить модуль
Get-Module -ListAvailable -Name <Name> #Показать установленный модуль
Get-Command -Module <Name> #Показать доступные команды установленного модуля
SqlServer
ScheduledTasks / Планировщик
Нажмите, чтобы отобразить
Список доступных команд:
Get-Command -Module ScheduledTasks
https://learn.microsoft.com/en-us/powershell/module/scheduledtasks/
Примеры:
Запуск от доменного пользователя
$Credential = Get-Credential -Credential "DOMAIN\sqlBackup"
Каждый час:
$Trigger = New-ScheduledTaskTrigger -Daily -At 00:30
$Principal = New-ScheduledTaskPrincipal -UserID "IDSCAN\sqlBackup" -LogonType Password
$Action = New-ScheduledTaskAction -Execute '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"' -Argument '-Command Invoke-Sqlcmd -Querytimeout 0 -ServerInstance sqlprod -InputFile Z:\SQL\TransactionLog.sql 2>&1> Z:\log\tl.log'
$Settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries -MultipleInstances Parallel
$Task = Register-ScheduledTask -TaskName "SQL\TransactionLog" -Trigger $Trigger -User $Credential.Username -Password $Credential.GetNetworkCredential().Password -Action $Action -Settings $Settings -Force
$Task.Triggers.Repetition.Duration = "P1D"
$Task.Triggers.Repetition.Interval = "PT1H"
$Task | Set-ScheduledTask -User $Credential.Username -Password $Credential.GetNetworkCredential().Password
P(eriod)0D(ays)T(ime)0H(ours)0M(inutes)0S(econds)
Каждый день:
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday,Tuesday,Thursday,Friday,Saturday,Sunday -At 05:10
$Principal = New-ScheduledTaskPrincipal -UserID "IDSCAN\sqlBackup" -LogonType Password
$Action = New-ScheduledTaskAction -Execute '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"' -Argument '-Command Invoke-Sqlcmd -Querytimeout 0 -ServerInstance sqlprod -InputFile Z:\SQL\Diff.sql 2>&1> Z:\log\diff.log'
$Settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries -MultipleInstances Parallel
$Task = Register-ScheduledTask -TaskName "SQL\Diff" -Trigger $Trigger -User $Credential.Username -Password $Credential.GetNetworkCredential().Password -Action $Action -Settings $Settings -Force
Еженедельный (с двумя действиями):
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Wednesday -At 05:00
$Principal = New-ScheduledTaskPrincipal -UserID "IDSCAN\sqlBackup" -LogonType Password
$Action = New-ScheduledTaskAction -Execute '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"' -Argument '-Command Invoke-Sqlcmd -Querytimeout 0 -ServerInstance sqlprod -InputFile Z:\SQL\Full.sql 2>&1> Z:\log\full.log'
$Action += New-ScheduledTaskAction -Execute '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"' -Argument '-File Z:\sql\Clear.ps1 2>&1> Z:\log\clear.log'
$Settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries -MultipleInstances Parallel
$Task = Register-ScheduledTask -TaskName "SQL\Full" -Trigger $Trigger -User $Credential.Username -Password $Credential.GetNetworkCredential().Password -Action $Action -Settings $Settings -Force
Один раз:
$Trigger = New-ScheduledTaskTrigger -Once -At 00:01
$Principal = New-ScheduledTaskPrincipal -UserID "IDSCAN\sqlBackup" -LogonType Password
$Action = New-ScheduledTaskAction -Execute '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"' -Argument '-Command Invoke-Sqlcmd -Querytimeout 0 -ServerInstance sqlprod -InputFile Z:\SQL\Test.sql 2>&1> Z:\log\test.log'
$Settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries -MultipleInstances Parallel
$Task = Register-ScheduledTask -TaskName "SQL\Test" -Trigger $Trigger -User $Credential.Username -Password $Credential.GetNetworkCredential().Password -Action $Action -Settings $Settings -Force
Ежемесячный:
$scheduler = New-Object -ComObject('Schedule.Service')
$scheduler.Connect()
$root = $scheduler.GetFolder('\')
$task = $scheduler.NewTask(0)
$trigger = $task.Triggers.Create(4)
$trigger.StartBoundary = [datetime]::new(2023, 1, 1, 1, 0, 0).ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.DaysOfMonth = 1
$action = $task.Actions.Create(0)
$action.Path = "C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe"
$action.Arguments = "-Command Invoke-Sqlcmd -Querytimeout 0 -ServerInstance sqlprod -InputFile Z:\SQL\FullBlobs.sql 2>&1> Z:\log\fullblobs.log"
$action.WorkingDirectory = "C:\Temp"
$task.Settings.ExecutionTimeLimit = "PT0S"
$task.Settings.MultipleInstances = 0
$root.RegisterTaskDefinition("SQL\FullBlobs", $task, 6, $Credential.Username, $Credential.GetNetworkCredential().Password, 1)
https://learn.microsoft.com/en-us/windows/win32/taskschd/taskfolder-registertaskdefinition
https://learn.microsoft.com/en-us/windows/win32/taskschd/monthlytrigger
https://learn.microsoft.com/en-us/windows/win32/api/taskschd/ne-taskschd-task_trigger_type2
https://learn.microsoft.com/en-us/windows/win32/taskschd/tasksettings
https://forums.powershell.org/t/create-monthly-scheduled-task/11829/3
Показать приоритет задачи (TaskPath не обязательно, если имя уникально):
(Get-ScheduledTask -TaskName "${TASKNAME}" -TaskPath "${TASKPATH}").Settings.Priority
Изменить приоритет (повысить до 4, по умолчанию 7):
$settings = New-ScheduledTaskSettingSet -Priority 4
Set-ScheduledTask -TaskName "${TASKNAME}" -Settings $settings
https://learn.microsoft.com/en-us/windows/win32/taskschd/tasksettings-priority
===== Информация о системе =====
<hidden><code powershell>
[System.Net.Dns]::GetHostByName($env:computerName).HostName #Сетевое имя системы
(Get-ComputerInfo).WindowsProductName #ОС
</code></hidden>
====== Проблемы ======
Не вводятся/печатаются буквы
Решение:
- <code powershell>Remove-Module PSReadLine</code>
- Закрыть powershell
- Удалить C:\Program Files\WindowsPowerShell\Modules\PSReadLine
- <code powershell>Install-Module PSReadLine</code>
https://danshin.ms/PSReadLine-problem/