Краткий учебник основ Powershell
Несколько лет назад мною писались заметки по Powershell.
В данном документе я их систематизирую и актуализирую.
На дворе начало 2018 года.
Powershell находится здесь:
C:\Windows\System32\WindowsPowerShell\v1.0
или
%SystemRoot%\System32\WindowsPowerShell\v1.0
Так-же имеется средство разработки - ISE (Integrated Script Environment)
powershell_ise.exe
Запуск сценариев PowerShell:
По умолчанию выполнение скриптов Windows PowerShell запрещено
Уровень Restricted – запрещает выполнение сценариев
Уровень Unrestricted – все сценарии могут запускаться
Уровень AllSigned – все сценарии должны иметь цифровую подпись
Уровень RemoteSigned – сценарии из сети долны быть подписаны
В реестре по пути: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell
Задается параметр например - "ExecutionPolicy"="AllSigned"
Либо управляем командлетами - Get-ExecutionPolicy и Set-ExecutionPolicy
Пример: Set-ExecutionPolicy RemoteSigned
Основная конструкция языка глагол-существительное.
Простые примеры:
Get-Help – вывести справку.
Get-Process – вывести список процессов.
Get-Command – вывести команды.
Передача параметров происходит через дефис «-».
Вывод команд с глаголом «Get»:
Get-Command –Verb Get
Вывод команд с существительным «Event»:
Get-Command –Noun event
Неявная передача параметра команде Get-help (справка по команде):
Get-Help Get-Event
Get-Help Get-Event –Detailed
Get-Help Get-Event -Full
Get-Help Get-Event -Examples
Список модулей в Powershell:
Get-Module –ListAvailable
Вывести все команды из модуля «NetTCPIP»:
Get-Command –Module NetTCPIP
Обновить справку(необходимо подключение к интернету и права администратора):
Update-Help
#Переменные среды
Get-Childitem env:
Get-Childitem env:
dir env: | sort name
#Вывод имя и значения переменной
Get-Item env:windir
Get-Childitem env:UserName
#Вывод значения переменной
write-host $env:windir
write-host $env:UserName
write-host ([System.Environment]::CurrentDirectory)
write-host ([System.Environment]::UserName)
#Изменение переменных (доступны командлеты Set-Item, Remove-Item, and Copy-Item)
$env:customvar = "Var1"
$env:customvar = $env:customvar + "Var2"
Set-Item -path env:customvar -value ($env:customvar + 'Var3')
Вывод порционно:
Get-Command | more
С сортировкой по столбцу Version:
Get-Command | Sort-Object Version
С сортировкой + вывод первых 50 строк:
Get-Command | Sort-Object Version | Select-Object -First 50
Вывести свойства и методы объектов:
Get-Service | Get-Member
Вывести только методы:
Get-Service | Get-Member -MemberType Method
Перенаправление вывода в файл:
Get-Service | Out-File "C:\test.txt"
Управление сервисом(с правами администратора):
Выбрали сервис:
Get-Service -Name AdobeARMservice
Что мы можем с ним делать:
Get-Command -Noun service
Рестартуем сервис:
Restart-Service AdobeARMservice
3.Работа с файловой системой
Какие есть команды для работы с файловой системой:
Get-Command -Noun item
Посмотреть содержимое директории(аналогично dir):
Get-ChildItem "C:\Program Files\7-Zip\"
Посмотреть все файлы по маске .exe, Recurse – вернет объекты, Force – покажет скрытые.
Get-ChildItem "C:\Program Files\7-Zip\" -Include *.exe -Recurse –Force
Удалить файл:
Remove-Item "C:\test.txt"
Создать папку:
New-Item -Path 'C:\temp\testfolder' -ItemType "directory"
Создать файл:
New-Item -Path 'C:\temp\testfolder\testfile.txt' -ItemType "file"
Удалить папку и содержимое:
Remove-Item 'C:\temp\testfolder' –Recurse
Работа со столбцами(оба примера равнозначны):
Для обработки используется конструкция @{}.
Ей передается аргумент в виде названия столбца n="Kbytes";
Далее происходит обработка столбца e={$PSItem.Length/1024}
$PSItem и $_ - ссылки на текущий объект.
Get-ChildItem "C:\Program Files\7-Zip\" | Select-Object -Property Name, Length, @{n="Kbytes"; e={$PSItem.Length/1024}}
Get-ChildItem "C:\Program Files\7-Zip\" | Select-Object -Property Name, Length, @{n="Kbytes"; e={$_.Length/1024}}
Вывод по маске в столбце:
Get-ChildItem "C:\Program Files\7-Zip\" | Where-Object Name -Like "7z*"
Операторы сравнения:
-eq Equal Равно
-ne Not equal Не Равно
-ge Greater than or equal Больше или Равно
-gt Greater than Больше
-lt Less than Меньше
-le Less than or equal Меньше или Равно
-like Wildcard comparison Использование символов подстановки для поиска соответствия образцу
-notlike Wildcard comparison Использование символов подстановки для поиска несоответствия образцу
-match Regular expression comparison Использование регулярных выражений для поиска соответствия образцу
-notmatch Regular expression comparison Использование регулярных выражений для поиска несоответствия образцу
-replace Replace operator Заменяет часть или все значение слева от оператора
-contains Containment operator Определение, содержит ли значение слева от оператора значение справа. В отличие от предыдущих операторов, результатом является булево значение
-notcontains Containment operator Определение того, что значение слева от оператора не содержит значение справа. Результатом является булево значение
Вывод, где размер больше или равен с поиском по маске:
Get-ChildItem "C:\Program Files\7-Zip\" | Where-Object -FilterScript {$_.Length -ge 150000 -and $_.Name -Like "7z.*"}
Вывод с общего занятого места объектами, с выводом максимального размера файла:
Get-ChildItem "C:\Program Files\7-Zip\" | Measure-Object -Property Length -Sum –Maximum
Вывод в форматированном виде, табуляция после Format-Table покажет варианты:
Get-ChildItem "C:\Program Files\7-Zip\" | Format-Table FullName, Extension, Length, Attributes
Посмотреть список стандартных переменных:
Get-Variable
Вывести значение переменной:
$PWD
Типы переменных:
[int] - целые числа
[single] - числа одинарной точности
[double] – числа двойной точности
[string] - текст
[char] - символ
[Boolean] – булево значение «Истина» \ «Ложь»
[datetime] - дата или время
Зададим значения переменных и произведем действие:
[int]$a = 10
[int]$b = 5
$a - $b
Конструкция if (elseif и else – необязательные блоки) – проверка условия:
[int]$a = 10
If ($a -eq 10){
Write-Host "a = 10"
}
ELSEIF ($a -gt 10){
Write-Host "a > 10"
}
ELSE {
Write-Host "a < 10"
}
Конструкция switch – проверяет значение:
[int]$a = 1
SWITCH ($a)
{
0 {Write-Host "a = 0"}
1 {Write-Host "a = 1"}
2 {Write-Host "a = 2"}
default {Write-Host "a - ?"}
}
Цикл while – выполняется, пока условие верно:
[int]$a = 1
WHILE ($a -lt 3){
Write-Host $a
$a = $a + 1
}
Аналогичная задача с while для цикла for:
FOR ([int]$a = 1; $a -lt 3; $a++){
Write-Host $a
}
Перебор с помощью цикла foreach:
$Process = Get-Process
FOREACH ($proc In $Process){
$proc.ProcessName + " - " + $proc.Id
}
Массивы, создание, обращение, перебор:
[int32[]]$Array = 1, 2, 3, 4
$Array[2]
FOR ([int]$i = 0; $i -lt $Array.count; $i++){
$Array[$i]
}
Обработка исключений(ошибок), введите число или символ:
Try {
[int]$num = Read-Host "Enter num"
6 / $num
} catch {
Write-Warning "Error"
}
Функции:
Простой пример и вызов:
Function Func{"func is work"}
Func
Пример с аргументами:
Function Func{"this is args: $Args"}
Func arg1 arg2
Еще пример с аргументами:
Function Func ($a, $b) {"this is args: $a $b"}
Func arg1 arg2
Пример с предопределенными значениями:
Function Func ($a="a1", $b="a2") {"this is args: $a $b"}
Func
#Пример функции
Function Func{ Param ([String]$arg1, $arg2) "this is arg1:" + $arg1 + " " + "this is arg2: " + $arg2}
Func arg11 arg22
#Классы
#Описание класса
class Writer {
#Свойства класса
[String]$OutDisk
[String]$OutDir = '\scripts\'
#Конструктор класса
Writer([String]$FilePath) {
$This.OutDir += $FilePath
$this.OutDir = $this.OutDisk + $this.OutDir
}
#Методы класса
[void]Write([String]$Per) {
'[{0} {1} {2}]' -f $(Get-Date), $Per, '#It Works!' |
Out-File $This.OutDir -Append -Encoding default
}
[int]GetSizeFile() {
return (Get-Item $This.OutDir).Length
}
}
#Создание экземпляра класса
$WriterObj = [Writer]::New('test.txt')
#Присваиваем значение свойству
$WriterObj.OutDisk = 'C:'
#Вызываем методы
$WriterObj.Write('Class Writer, method Write')
$WriterObj.GetSizeFile()
#SQL
#С помощью командлета invoke-sqlcmd на самом SQL сервере
$conn = invoke-sqlcmd -ServerInstance 'Адрес_Сервера' -database Имя_БД -Query "SQL_Запрос";
echo $conn >> C:\scripts\out.txt;
#Пример подключения под доменной авторизацией с помощью класса SqlConnection библиотеки классов .NET Framework
$SqlServer = "Адрес_Сервера";
$SqlCatalog = "Имя_БД";
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SqlServer; Database=$SqlCatalog; Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = $SqlConnection.CreateCommand()
$SqlCmd.CommandText = "SQL_Запрос"
$objReader = $SqlCmd.ExecuteReader()
while ($objReader.read()) {
'[{0} {1}]' -f $objReader.GetValue(0), $objReader.GetValue(1)
}
$objReader.close()
$SqlConnection.Close()
#Пример подключения под SQL авторизацией с помощью класса SqlConnection библиотеки классов .NET Framework
$SqlServer = "Адрес_Сервера";
$SqlCatalog = "Имя_БД";
$SqlLogin = "Логин_Пользователя";
$SqlPassw = "Пароль_Пользователя"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SqlServer; Database=$SqlCatalog; User ID=$SqlLogin; Password=$SqlPassw;"
$SqlConnection.Open()
$SqlCmd = $SqlConnection.CreateCommand()
$SqlCmd.CommandText = "SQL_Запрос"
$objReader = $SqlCmd.ExecuteReader()
while ($objReader.read()) {
'[{0} {1}]' -f $objReader.GetValue(0), $objReader.GetValue(1)
}
$objReader.close()
$SqlConnection.Close()
#Пример исполнения SQL запросов с изменением данных ($SqlCmd.ExecuteNonQuery() | Out-Null - подавляет вывод результатов выполнения запроса)
$SqlServer = "Адрес_Сервера";
$SqlCatalog = "Имя_БД";
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SqlServer; Database=$SqlCatalog; Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = $SqlConnection.CreateCommand()
$SqlCmd.CommandText = "delete from [dbo].[tasks]"
$SqlCmd.ExecuteNonQuery() | Out-Null
$SqlConnection.Close()
#Работа с почтой по SMTP
#Параметры подключения
$ConstServer = "mail.domain.ru" #Адрес SMTP сервера
$ConstSMTPPort = "25" #Порт SMTP сервера
$ConstFrom = "sender@domain.ru" #Адрес отправителя сообщения
[string[]]$ConstTo = "one@domain.ru","two@domain.ru" #Адреса получателей сообщения
$ConstMessageTypeHTML = $true #Формат сообщения HTML - true, обычный текст - false
$ConstUserName = "sender" #Имя пользователя (ящика) для авторизации на сервере SMTP
$ConstUserPass = "Пароль_Учетки" #Пароль авторизации пользователя на сервере SMTP
$ConstMessageSubject = "Тема сообщения" #Тема сообщения
$ConstMessageBody = "Текст сообщения" #Тело сообщения
$SourceFile='C:\temp\attach.txt' #Прикрепляемый файл
#Создаем подключение:
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$SmtpClient.Host = $ConstServer
$SmtpClient.Port = $ConstSMTPPort
$SmtpClient.EnableSsl = $false
$SmtpClient.Credentials= New-Object System.Net.NetworkCredential($ConstUserName , $ConstUserPass)
#Создаем сообщение:
$Message = New-Object System.Net.Mail.MailMessage
$Message.From = $ConstFrom
$Message.To.Add($ConstTo)
$Message.BodyEncoding = [System.Text.Encoding]::UTF8
$Message.SubjectEncoding = [System.Text.Encoding]::UTF8
$Message.IsBodyHtml = $ConstMessageTypeHTML
$Message.Subject = $ConstMessageSubject
$Message.Attachments.Add($SourceFile)
$Message.Body = (get-date).ToString() + "<br>" + $ConstMessageBody"
#Соединение
$SmtpClient.Send($Message) #Отправляем SMTP сообщение
if($?) { write-host "Сообщение успешно отправлено" } else{ write-host "Сообщение небыло отправлено, ошибка:" $Error[0].ToString() }
$Message.Dispose() #Команда QUIT для SMTP-сервера, завершает TCP-подключение и высвобождает ресурсы, текущего соединения