Какие скрытые особенности PowerShell?
Заставить функции Powershell действительно вернуть массив, даже пустой массив.
Из-за того, как реализован синтаксис @ (), функции не всегда могут возвращать массив, как ожидалось, например следующий код вернет $ null и НЕ пустой массив. Если вы тестируете код с помощью set-StrictMode -On
набор, вы получите PropertyNotFoundStrict
вместо этого при попытке сослаться на .count
свойство:
function test
{
#some code that might return none,one or multiple values
$data = $null
return @($data)
}
(test).count
Просто добавив ,
к @()
обойдёт "синтаксический сахар", и вы получите фактический массив, даже если он пуст:
function test2
{
#some code that might return none,one or multiple values
$data = $null
return ,@($data)
}
(test2).count
Создавайте собственные пользовательские функции и сохраняйте их в своем профиле. Вы можете создать массу полезных функций, не задумываясь каждый раз, когда возникает подобная проблема.
Редактировать профиль:
PS C:\> notepad $profile
Доступ к любым классам .net с помощью Add-Type -Assembly
с именем сборки, или Add-Type -Path
с путем dll, а затем используя синтаксис вроде [Namespace.Dotted.ClassName+NestedClass]::StaticMethod()
создать New-Object Namespace.Dotted.ClassName
или вызывать статические методы / поля для типов.
Сохраняйте файлы, используя кодировку, отличную от UTF-16 в ISE.
По умолчанию Powershell ISE сохраняет все файлы в кодировке «Unicode Big Endian» (UTF-16). Следующий код создаст пункт меню в ISE и назначит горячую клавишу (по умолчанию Ctrl-Shift + E) для сохранения файла на текущей вкладке PowerShellISE с использованием указанной кодировки, отличной от UTF-16. Я установил его в UTF-8, но вы можете использовать ASCII или что-то еще, если хотите.
$iseProfile = $profile -replace '_profile','ISE_profile'
$addMenuCmdStr = '$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add("_Save as UTF8",{$psIse.CurrentFile.Save([System.Text.Encoding]::UTF8)},"Ctrl+Shift+E")'
add-content $iseProfile -value $addMenuCmdStr
ise
Этот трюк полезен, чтобы избежать некоторых проблем со скриптами PowerShell, таких как:
Subversion (возможно, другие системы CVS) добавляет файлы .ps1 в репозиторий как двоичные, а не как простой текст, не позволит вам «различать» ваши сценарии, потому что они «двоичные», или генерирует ошибку, что файл не может быть добавлен потому что это "двоичный тип пантомимы". Изменение кодировки на UTF-8 должно позволить добавлять ваши файлы в репозиторий с помощью svn: mime-type / text-plain и позволить работать функциям diff.
Код подписи с использованием set-AuthenticodeSignature не работает для некоторых файлов, но не для других
Вероятно, в других случаях операции с содержимым файлов работали для одних файлов, а не для других, часто без видимой причины, но одним из симптомов является то, что проблема возникает только у файлов, созданных с помощью ISE.
Брызги. Вы можете определить набор аргументов в Hashtable, а затем использовать их в качестве параметров функции.
$sendMailParameters = @{
To = 'someone@somebody.com'
From ='someone@somebody.com'
Subject = 'Something'
Body = 'Some stuff'
BodyAsHtml = $true
}
Send-MailMessage @sendMailParameters
Перехожу к ответу, чтобы я не чувствовал себя плохо, создавая коммвики.
Циклы по каждому элементу:
PS C:\> foreach ($a in "a","b","c") { write $a }
a
b
c
Изменен на путь UNC:
PS C:\> cd \\kcws\c$
PS Microsoft.PowerShell.Core\FileSystem::\\kcws\c$>
Получите запущенные услуги:
PS C:> get-service | где {$ _. status -eq "работает"}
Status Name DisplayName
------ ---- -----------
Running AeLookupSvc Application Experience
Running Appinfo Application Information
Running AudioEndpointBu... Windows Audio Endpoint Builder
Running Audiosrv Windows Audio
[...]
Это скорее неочевидная проблема, но однажды я написал сценарий для создания файла CSV в качестве входных данных для более старого исполняемого файла ofiller.exe, который используется с межсетевыми экранами Checkpoint.
Я использовал перенаправление вывода: Script.ps1 > outfile.csv
Мой CSV-файл, созданный с помощью PowerShell, не работал, тогда как мой рукописный тестовый CSV-файл работал нормально, хотя эти два файла различались одинаково. Только когда я посмотрел на размер файлов, я понял, что это проблема Unicode Vs ASCII; CSV PowerShell был вдвое больше.
Связывание моего вывода с | Out-File -format ASCII -name outfile.csv
вместо дешевого и веселого перенаправления STDOUT проблему решил.