Выучить PowerShell за 30 минут. Постигаем автоматизацию Qlik
PowerShell – это сценарный язык программирования Windows и фреймворк для управления конфигурацией приложений Windows, основанных на .NET Framework. Windows 7 и выше поставляются с PowerShell.
Почти все приведенные ниже примеры могут быть частью shell-скрипта или выполнены напрямую в среде shell.
Ключевым отличием от Bash является то, что PowerShell в основном это объекты, которыми вы управляете, а не обычный текст.
Если вы не уверены в своей среде:
1 2 3 4 5 6 7 8 9 10 11 |
Get-ExecutionPolicy -List Set-ExecutionPolicy AllSigned # Политика "Execution" включает в себя: # - Restricted: Скрипты не будут выполняться. # - RemoteSigned: Скаченные скрипты выполняются только в том случае, если они подписаны доверенным издателем. # - AllSigned: Скрипты должны быть подписаны доверенным издателем. # - Unrestricted: Запуск всех скриптов. help about_Execution_Policies # для получения дополнительной информации # Текущая версия PowerShell: $PSVersionTable |
Получить помощь:
1 2 3 4 5 6 7 8 9 10 11 12 |
# Найти команды Get-Command about_* # alias: gcm Get-Command -Verb Add Get-Alias ps Get-Alias -Definition Get-Process Get-Help ps | less # alias: help ps | Get-Member # alias: gm Show-Command Get-EventLog # Отобразить графический интерфейс пользователя (GUI) для заполнения параметров Update-Help # Запуск от имени администратора |
Учебник начинается здесь:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# Как вы уже поняли, комментарии начинаются с # # Простой пример приветствия: echo Hello world! # echo это псевдоним для Write-Output (=cmdlet) # Большинство cmdlets и функций следуют соглашению об именах Verb-Noun # Каждая команда начинается с новой строки или после точки с запятой: echo 'This is the first line'; echo 'This is the second line' # Объявление переменной выглядит следующим образом: $aString="Some string" # Или вот так: $aNumber = 5 -as [double] $aList = 1,2,3,4,5 $aString = $aList -join '--' # yes, -split exists also $aHashtable = @{name1='val1'; name2='val2'} # Использование переменных: echo $aString echo "Interpolation: $aString" echo "$aString has length of $($aString.Length)" echo '$aString' echo @" This is a Here-String $aString "@ # Обратите внимание, что ' (одинарная кавычка) не будет расширять переменные! # Here-Strings также работают с одинарной кавычкой # Встроенные переменные: # Существуют некоторые полезные встроенные переменные, например echo "Booleans: $TRUE and $FALSE" echo "Empty value: $NULL" echo "Last program's return value: $?" echo "Exit code of last run Windows-based program: $LastExitCode" echo "The last token in the last line received by the session: $$" echo "The first token: $^" echo "Script's PID: $PID" echo "Full path of current script directory: $PSScriptRoot" echo 'Full path of current script: ' + $MyInvocation.MyCommand.Path echo "FUll path of current directory: $Pwd" echo "Bound arguments in a function, script or code block: $PSBoundParameters" echo "Unbound arguments: $($Args -join ', ')." # Больше встроенных переменных: `help about_Automatic_Variables` # Inline (встроить) другой файл (оператор точки) ..\otherScriptName.ps1 ### Управление потоком выполнения инструкций # У нас есть обычная структура: if ($Age -is [string]) { echo 'But.. $Age cannot be a string!' } elseif ($Age -lt 12 -and $Age -gt 0) { echo 'Child (Less than 12. Greater than 0)' } else { echo 'Adult' } # Оператор switch более мощные по сравнению с большинством языков $val = "20" switch($val) { { $_ -eq 42 } { "The answer equals 42"; break } '20' { "Exactly 20"; break } { $_ -like 's*' } { "Case insensitive"; break } { $_ -clike 's*'} { "clike, ceq, cne for case sensitive"; break } { $_ -notmatch '^.*$'} { "Regex matching. cnotmatch, cnotlike, ..."; break } { 'x' -contains 'x'} { "FALSE! -contains is for lists!"; break } default { "Others" } } # Классика for($i = 1; $i -le 10; $i++) { "Loop number $i" } # или короче 1..10 | % { "Loop number $_" } # PowerShell также предлагает foreach ($var in 'val1','val2','val3') { echo $var } # while () {} # do {} while () # do {} until () # Обработка исключений try {} catch {} finally {} try {} catch [System.NullReferenceException] { echo $_.Exception | Format-List -Force } ### Провайдеры # Список файлов и каталогов в текущем каталоге ls # or `dir` cd ~ # goto home Get-Alias ls # -> Get-ChildItem # Uh!? These cmdlets have generic names because unlike other scripting # languages, PowerShell does not only operate in the current directory. cd HKCU: # go to the HKEY_CURRENT_USER registry hive # Get all providers in your session Get-PSProvider ### Pipeline # Cmdlets have parameters that control their execution: Get-ChildItem -Filter *.txt -Name # Get just the name of all txt files # Only need to type as much of a parameter name until it is no longer ambiguous ls -fi *.txt -n # -f is not possible because -Force also exists # Use `Get-Help Get-ChildItem -Full` for a complete overview # Results of the previous cmdlet can be passed to the next as input. # `$_` is the current object in the pipeline object. ls | Where-Object { $_.Name -match 'c' } | Export-CSV export.txt ls | ? { $_.Name -match 'c' } | ConvertTo-HTML | Out-File export.html # If you get confused in the pipeline use `Get-Member` for an overview # of the available methods and properties of the pipelined objects: ls | Get-Member Get-Date | gm # ` is the line continuation character. Or end the line with a | Get-Process | Sort-Object ID -Descending | Select-Object -First 10 Name,ID,VM ` | Stop-Process -WhatIf Get-EventLog Application -After (Get-Date).AddHours(-2) | Format-List # Use % as a shorthand for ForEach-Object (a,b,c) | ForEach-Object ` -Begin { "Starting"; $counter = 0 } ` -Process { "Processing $_"; $counter++ } ` -End { "Finishing: $counter" } # Get-Process as a table with three columns # The third column is the value of the VM property in MB and 2 decimal places # Computed columns can be written more verbose as: # `@{name='lbl';expression={$_}` ps | Format-Table ID,Name,@{n='VM(MB)';e={'{0:n2}' -f ($_.VM / 1MB)}} -autoSize ### Functions # The [string] attribute is optional. function foo([string]$name) { echo "Hey $name, have a function" } # Calling your function foo "Say my name" # Functions with named parameters, parameter attributes, parsable documentation <# .SYNOPSIS Setup a new website .DESCRIPTION Creates everything your new website needs for much win .PARAMETER siteName The name for the new website .EXAMPLE New-Website -Name FancySite -Po 5000 New-Website SiteWithDefaultPort New-Website siteName 2000 # ERROR! Port argument could not be validated ('name1','name2') | New-Website -Verbose #> function New-Website() { [CmdletBinding()] param ( [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [Alias('name')] [string]$siteName, [ValidateSet(3000,5000,8000)] [int]$port = 3000 ) BEGIN { Write-Verbose 'Creating new website(s)' } PROCESS { echo "name: $siteName, port: $port" } END { Write-Verbose 'Website(s) created' } } ### It's all .NET # A PS string is in fact a .NET System.String # All .NET methods and properties are thus available 'string'.ToUpper().Replace('G', 'ggg') # Or more powershellish 'string'.ToUpper() -replace 'G', 'ggg' # Unsure how that .NET method is called again? 'string' | gm # Syntax for calling static .NET methods \[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') # Note that .NET functions MUST be called with parentheses # while PS functions CANNOT be called with parentheses. # If you do call a cmdlet/PS function with parentheses, # it is the same as passing a single parameter list $writer = New-Object System.IO.StreamWriter($path, $true) $writer.Write([Environment]::NewLine) $writer.Dispose() ### IO # Reading a value from input: $Name = Read-Host "What's your name?" echo "Hello, $Name!" [int]$Age = Read-Host "What's your age?" # Test-Path, Split-Path, Join-Path, Resolve-Path # Get-Content filename # returns a string[] # Set-Content, Add-Content, Clear-Content Get-Command ConvertTo-*,ConvertFrom-* ### Useful stuff # Refresh your PATH $env:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") # Find Python in path $env:PATH.Split(";") | Where-Object { $_ -like "*python*"} # Change working directory without having to remember previous path Push-Location c:\temp # change working directory to c:\temp Pop-Location # change back to previous working directory # Aliases are: pushd and popd # Unblock a directory after download Get-ChildItem -Recurse | Unblock-File # Open Windows Explorer in working directory ii . # Any key to exit $host.UI.RawUI.ReadKey() return # Create a shortcut $WshShell = New-Object -comObject WScript.Shell $Shortcut = $WshShell.CreateShortcut($link) $Shortcut.TargetPath = $file $Shortcut.WorkingDirectory = Split-Path $file $Shortcut.Save() |
Настройка оболочки PowerShell:
1 2 3 4 5 6 7 |
# $Profile полный путь до вашего файла `Microsoft.PowerShell_profile.ps1` # Весь код будет выполнен, когда начнется сеанс PS if (-not (Test-Path $Profile)) { New-Item -Type file -Path $Profile -Force notepad $Profile } # Больше информации: `help about_profiles` |