Posts on this page:
Собственно, добавлять тут особо нечего :-). Детали нового релиза можно прочитать здесь и здесь. А остальное здесь:
Однако, хочу добавить одну полезную (для меня) вещицу. На главной я вывешиваю список всех командлетов, которые есть в модуле с алиасами, если есть и ссылками на страницы wiki со справкой для командлетов. Некоторые могут подумать, что я это делаю вручную (первый раз я действительно делал в ручную и сильно устал). Конечно же, можно делать вручную, а можно и автоматически генерировать текст (если быть точнее, полный код HTML) при помощи PowerShell. Здесь есть много логики — ссылки на справку командлетов содержат их названия: http://pspki.codeplex.com/wikipage?title=CmdletName. Т.е. достаточно иметь основную часть ссылки и просто в конец добавлять название командлета. Однако, для ряда командлетов я применяю алиасы, чтобы можно было вводить команды покороче. Чтобы определить, есть ли у командлета алиасы, можно сделать вот так:
PS C:\> Get-Alias -Definition Get-Alias CommandType Name Definition ----------- ---- ---------- Alias gal Get-Alias PS C:\>
Вот так вы можете узнать, есть ли у командлета алиас или нету (тогда пошик насыпет вам много красного). Т.е. можно написать несколько строчек кода:
# через Get-Command получаем список команд, типа функции (по дефолту Get-Command # выдаёт всё, что относится к командам, включая алиасы), которые относятся к # конкретному модулю gcm -Module pki -CommandType function | %{ # определяем, есть ли алиас у командлета $alias = gal -Definition $_.name -ea 0 # если есть, тогда делаем код HTML с алиасом if ($alias) { @" <li><a href="http://pspki.codeplex.com/wikipage?title=$($_.name)">$($_.name)</a> (Alias: <strong>$($alias.name)</strong>) </li> "@ } else { # если нету, тогда просто код HTML без алиаса @" <li><a href="http://pspki.codeplex.com/wikipage?title=$($_.name)">$($_.name)</a> </li> "@} }
и всё. Просто в конце добавляете '| clip', чтобы он весь код HTML не выкидывал в консоль, а буфер обмена и получаете профит. Просто вставляете в редактор кодеплекса и всё.
Естественно, это была реклама пошика :-)
В разных интернетах ходят разные толки по поводу Policy CA. В своё время я давал краткую справку о нём: Обсуждение схем иерархии Certification Authority и есть необходимость немного дополнить ту статью и показать применением выделенного Policy CA в реальном мире. Назначение Policy CA вполне понятно — разделять PKI на одну или несколько веток, которые будут различаться правилами выдачи и обслуживания сертификатов. Интернеты (и разные там специалисты) всячески рекомендуют деплоить 3-х уровневые иерархии вида:
Offline Root CA
Offline Policy CA
Online Issuing CA
Это считается бест-практисом. Отдельные люди указывали мне, что совмещение ролей (Policy и Issuing) не есть хорошо по причине безопасности и всё такое. Но если говорить о бест-практисах, то их здесь нету совсем. Есть только некоторые рекомендации, по которым можно подобрать себе оптимальную иерархию. Всё остальное является следствием буйной фантазии. Давайте ещё раз пробежимся по этим моментам.
Если у вас небольшая компания (скажем, человек 10-100) без особых требований к PKI, вы спокойно разворачиваете одноуровневую иерархию с Online Root CA и используете сертификаты для логона (VPN, IIS и/или применяете смарт-карты) или шифруете данные. Как пример. Хоть я в предыдущей статье весьма критически относился к такому решению, оно в реальном мире вполне себе жизнеспособно (опыт иногда меняет отношение к каким-то вопросам в ту или иную сторону). Не потому что она ВНЕЗАПНО стала безопасной, а потому что это элементарно выгодней, чем покупать отдельное железо и лицензию Windows Server, даже если посчитать все риски. Плюс, экономия на административных издержках. Т.е. это случаи, когда компрометация PKI не ведёт к краху всего бизнеса, хотя это не очень приятно.
Для сравнения можно представить, сколько администраторов не делает бакупов. Бакупы — это вообще отдельная тема и ситуация с ними катастрофическая. Вы просто не представляете сколько компаний не делают бакупы. А когда один единственный (или парочка) выходят из строя, теряя всю финансовую отчётность и вообще всё, чем занималась компания — этот фейл более реальный и более эпический.
Если вы интегрируете PKI в свою сеть более тесно (вы внедряете цифровые подписи, устанавливаете VPN между сайтами, появляются удалённые SCCM/OpsMgr клиенты и т.д.), вы скорее всего будете более благоразумны и примените 2-х или 3-х уровневую иерархию. На этом этапе у вас PKI может начать делиться, потому что сферы применения PKI становятся шире. И вот здесь может появиться желание вбахать выделенный Policy CA, который опишет политику применения (CPS) сертификатов в вашей организации. С одной стороны это выглядит идеологически правильно. Но с другой стороны это не очень практично. Дело в том, что CPS можно прикрутить и к издающим CA, совместив роль Policy и Issuing CA. Об этом я уже писал в предыдущей статье.
Даже если у вас на уровне шаблонов сертификатов действуют разные политики, их вполне возможно описать в пределах одного CPS. Политики на уровне шаблонов могут быть очень разнообразные: например, чтобы получить сертификат для шифрования данных достаточно залогониться в систему. А чтобы получить логонный сертификат на смарт-карте, нужно оформить соответствующую заявку и нотариально заверить у руководителя отделом. Для получения сертификата цифровой подписи (для подписи документов), нужно в должности быть руководителем какого-то отдела. Это наиболее распространённые примеры из реальной жизни.
Учитывая, что в этих случаях у вас будет один CPS, вы можете на уровне издающего CA применить OID = All Issuance Policies (2.5.29.32.0) в CAPolicy.inf:
[PolicyStatementExtension]
Policies = SomeCPS[SomeCPS]
URL = Some URL
OID = 2.5.29.32.0
Т.е. CA может выдавать сертификаты с использованием любых политик выдачи и использования сертификатов, которые более конкретно определены в CPS. Так же, данный сценарий позволяет провести последующую кросс-сертификацию с другой PKI (см. Что в OID'е тебе моём?). Если CA может издавать сертификаты только по конкретным политикам, вы можете ограничить CA только ими, применив следующий шаблон для CAPolicy.inf:
[PolicyStatementExtension]
Policies = CPS1, CPS2, CPS3[CPS1]
URL = URL1
OID = 1.3.6.1.4.1.12345.1[CPS2]
URL = URL2
OID = 1.3.6.1.4.1.12345.2[CPS3]
URL = URL3
OID = 1.3.6.1.4.1.12345.3
В результате, CA сможет выдавать сертификаты на основе тех шаблонов (здесь я имею ввиду применение в Windows PKI), где эти политики определены.
Заметка: всякие верисайны, тафты и прочие коммерческие CA как правило применяют 1-2 уровневые (хотя есть и 3-х уровневые) иерархии. Но у них специфика другая.
Если всё так просто умещается в 2-х уровневой иерархии, когда же нам может понадобиться выделенный Policy CA?
Наконец-то добрались до цели нашей экскурсии. В реальной жизни выделенный Policy CA потребуется только когда у вас будут две и более совершенно разных политик выдачи и использования сертификатов. Наиболее классический случай — когда вы ведёте бизнес в разных странах.
Например, в России у вас головной офис, а в Европе у вас находится филиал. В этом случае у вас скорее всего политики выдачи для родной страны и Европы будут очень сильно отличаться, потому что законодательства в этих странах тоже разные. Но и здесь возможны варианты. Если все CA находятся в головном офисе (и европейский офис подключается к головному через VPN), вы можете рассмотреть предыдущий раздел. Это означает, что вы сделаете 2 издающих CA: один для локального офиса, второй для европейского. Естественно, на каждом CA будут описаны различные политики сертификатов.
Если же в европейском филиале находится свой CA и им управляет местный персонал, тогда понадобится выделенный Policy CA. Т.е. вы в головном офисе установите Policy CA, ограничите его на уровне CPS и тогда европейский офис может спокойно управлять своими издающими CA без риска нарушить политики сертификатов. При этом, для головного офиса вы можете использовать 2-х уровневую иерархию. Разумеется, в этом случае для Policy CA вы не сможете использовать All Issuance Policies, а нужно применить свой кастомный OID (или несколько, см предыдущий раздел).
Схожий сценарий: у вас есть большое количество филиалов, в каждом установлен свой издающий CA (но все они подчинаются одному корневому CA), т.к. интернеты между ними не очень шустрые и стабильные. И каждым CA в филиале управляет своя команда администраторов. В этом случае есть смысл (но совершенно не обязательно) под корнем установить Policy CA, на нём определить CPS и уже под ним размещать издающие CA филиалов. В этом случае от администраторов филиалов не требуется лишних телодвижений по прописыванию CPS в CAPolicy.inf, потому что CPS определённые на Policy CA будут наследоваться на сертификаты издающих CA.
Следующий сценарий, более специфический: вы хотите сделать root signing. Root signing — это когда коммерческий CA (VeriSign, Thawte, etc) выдаёт сертификат для вашего CA. В этом случае вы исключаете проблему организации доверия вашим сертификатам, потому что все сертификаты в этом случае будут заканчиваться корневым CA верисайна или какого-нибудь другого well-known коммерческого CA. В этом случае коммерческий CA выдаст сертификат для вашего выделенного Policy CA, который не может быть совмещён с издающим (это одно из требований к root signing).
Ещё один специфический сценарий: в вашей компании несколько лесов Active Directory. Если вы не применяете cross-forest enrollment, вам вероятнее всего придётся сделать выделенный Policy CA, который определит общую политику сертификатов для всех лесов Active Directory. И в каждом лесу уже устанавливаете издающие CA. Если же каждый лес будет иметь свой независимый набор политик сертификатов, можно ограничиться двумя уровнями.
Последний сценарий в этом разделе: вы планируете кросс-сертификацию с другой PKI. При этом под кросс-сертификацию должны подпадать все ваши издающие CA. В этом случае у вас есть выбор — оставаться на 2-х уровнях и получить на каждый CA по кросс-сертификату или сделать выделенный Policy CA и тогда получите только 1 кросс-сертификат. Вы можете сказать, что можно же получить один кросс-сертификат для корневого CA и тогда все издающие CA будут подпадать под кросс-сертификацию. С одной стороны это действительно возможно. Но кросс-сертификация подразумевает наличие CPS (а так же возможны внешние аудиты на предмет следования собственному CPS), который никогда на корневых CA не определяется.
Про 4-х уровневую иерархию я ничего рассказывать не буду, потому что не посчастливилось лицезреть такое. Если что, можете прочитать об этом в книге Комара —http://www.sysadmins.lv/pkibookshelf.aspx. А мы, в свою очередь, немного освежили память об иерархиях в PKI и более детально рассмотрели некоторые аспекты, касающиеся Policy CA и разрушили миф о бест-практичности 3-х уровневой иерархии. Т.е. каждая PKI строится с учётом требований бизнеса и управления, а не бизнес и управление строятся под конкретную выбранную иерархию и этот пост лишь раскрывает некоторые аспекты, которыми можно руководствоваться для проектировании PKI.
В любом случае, как сделаете — так и будет хорошо. Лишь бы вы (как проектировщик PKI) подошли к делу с головой и ваше решение заработало, как запланировало.
Как вы знаете, 9 и 10 ноября состоится мероприятие Tech·Ed Russia. Если не знаете, дальше можете не читать. Наверняка вы не знаете, что я там буду присутствовать. Зато теперь знаете. И если есть желающие (только для участников мероприятия) встретиться/познакомиться (интим не предлагать), можете меня найти в зоне Ask the Experts у стенда Information Security. Мои часы приёма:
9 ноября
Time | Hours | Stand |
12.30-14.30 | 2 | Information Security |
16.00-18.00 | 2 | Information Security |
10 ноября
Time | Hours | Stand |
10.00-12.00 | 2 | Information Security |
17.00-19.00 | 2 | Information Security |
У стенда можно обсудить PowerShell, PKI, SRP, Applocker, или просто вспомнить про великих троллей тридцателетней войны.
Теоретически меня можно будет найти и в другие часы, просто ищите меня по аватарке в толпе.
Примечание: сведения в данной статье могут содержать фрагменты диктовки Капитана Очевидности и скорее всего приведены только для освежения памяти.
Давным-давно, Вася Гусев как-то сотворил артикль: Непонятные штуки – $_ и %. Как показала практика (хотя, я с этой практикой не сильно согласен), эти штуки до сих пор (даже после Васиного срыва покровов) остаются непонятными для рядовых администраторов у которых нет интегрированного парсера и отладчика скриптов в голове. Если со знаком процента ещё можно бороться (т.е. не использовать его в качестве алиаса Foreach-Object), то с $_ бороться тяжело. Тут даже дело не в том, что бороться, а просто объяснить пользователям, что это такое. Что это такое — можно почитать у Васи. Если вы ленивые, тогда объясняю: $_ представляет собой динамическую переменную, которая хранит значение текущего элемента в конвейере.
Пара слов о понимании. Например, переменная $files для пользователя выглядит достаточно понятной — в ней какой-то список файлов. $_ для пользователя уже непонятна — в ней хранится нечто. В PowerShell 2.0 появилась возможность избежать использования этой мутной перменной в advanced functions. Вот краткая история:
function EnumItems { process { Write-Host Current pipeline item: $_ } }
И запустите: 1..5 | EnumItems 0
Здесь других вариантов представить текущий элемент конвейера не представляется возможным, только через $_.
В PowerShell 2.0 предыдущий код будет работать, пока вы не превратите простую функцию в advanced:
function EnumItems { [CmdletBinding()] param($a) process { Write-Host Current pipeline item: $_ } }
В таком виде функция не заработает уже. Дело в том, что в advanced functions вы обязаны использовать конструкцию param() для определения аргументов, которые эта функция принимает. Причём, если функция не принимает никаких внешних аргументов, а принимает только данные из конвейера вы всё равно должны это отразить в конструкции param().
function EnumItems { [CmdletBinding()] param([Parameter(ValueFromPipeline = $true)]$a) process { Write-Host Current pipeline item: $a } }
Теперь можно запускать функцию: 1..5 | EnumItems
Зато в стадии Process (которая запускается для каждого элемента в конвейере) вы теперь можете совершенно невозбранно использовать не $_, а нормальное имя переменной, которая принимает значения из конвейера. Это делает функцию более читабельной. А что с остальными? Try {} Catch {}, trap {}, Foreach-Object {}? В этих конструкциях для обозначения текущего элемента конвейера используется закорючка $_.
Для улучшения (или упрощения) понимания сути переменной $_ в PowerShell 3.0 сделали алиас для неё — $psitem. $psitem можно использовать абсолютно везде, где вы можете использовать $_:
1..5 | ForEach-Object {$psitem} function DivideByZero { try {1/0} catch {Write-Host $psitem} }
Да, в catch {} можно использовать переменную $_ или $psitem, которая представляет собой текущий элемент ошибки — $error[0]. Или ещё вот:
switch (1..5) { 1 {$psitem} }
В конструкции switch тоже можно использовать $_, или $switch.current, или $psitem , которые представляют одно и то же — текущий элемент энумератора.
Вернёмся к истории. Во времена PowerShell 1.0 мы писали какие-то интерактивные функции, которые требовали ввода каких-то данных пользователем и внутренняя логика функции что-то с ними делала. Но пользователи (включая администраторов и разработчиков этой функции) — существа доволно-таки, неблагодарные и всегда наровят что-нибудь поделить на ноль и, в конечном итоге, всё сломать. Всё что угодно, лишь бы не работать. Для этого в первых функциях приходилось писать кучу бессмысленного кода, который выполнял одну задачу — проверить, что пользователь ввёл те данные, которые функция ожидает получить. Например, пользователь должен указать хоть какие-то аргументы, а не просто выполнить функцию без указания каких-либо данных. Например, если параметр работает с числами, функция должна быть защищена от пользователя-вредителя, который обязательно в параметр укажет строку, а не число и многое другое. В PowerShell 1.0 создание защиты от дураков и прочих вредителей было не самым простым делом.
В PowerShell 2.0 коварные разработчики PowerShell (с Джефри Сновером во главе отряда) придумали advanced functions. Это позволило писателям функций резко повысить свою производительность за счёт более продвинутых средств борьбы с анонимусомвредителями. Для этого в параметрах функции можно указывать более конкретные фильтры для принимаемых данных. Вот пример:
function Foo { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateCount(1,7)] [ValidatePattern("Bad|Locked|Missed|New|Ok|Total|Unknown")] [String[]]$show ) }
Если оградить параметр вот такими атрибутами, пользователь будет вынужден:
Вот что мы получим, если не будем соблюдать эти требования:
[↓] [vPodans] function Foo { >> [CmdletBinding()] >> param( >> [Parameter(Mandatory = $true)] >> [ValidateCount(1,7)] >> [ValidatePattern("Bad|Locked|Missed|New|Ok|Total|Unknown")] >> [String[]]$show >> ) >> } >> [↓] [vPodans] foo cmdlet Foo at command pipeline position 1 Supply values for the following parameters: show[0]: Foo : Cannot validate argument on parameter 'show'. The number of supplied arguments (0) is less than the minimum numbe r of allowed arguments (1). Specify more than 1 arguments and then try the command again. At line:1 char:4 + foo <<<< + CategoryInfo : InvalidData: (:) [Foo], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Foo [↓] [vPodans] foo nya! Foo : Cannot validate argument on parameter 'show'. The argument "nya!" does not match the "Bad|Locked|Missed|New|Ok|To tal|Unknown" pattern. Supply an argument that matches "Bad|Locked|Missed|New|Ok|Total|Unknown" and try the command agai n. At line:1 char:4 + foo <<<< nya! + CategoryInfo : InvalidData: (:) [Foo], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Foo [↓] [vPodans] foo bad, bad, bad, bad, bad, bad, bad, bad Foo : Cannot validate argument on parameter 'show'. The number of supplied arguments (8) exceeds the maximum number of allowed arguments (7). Specify less than 7 arguments and then try the command again. At line:1 char:4 + foo <<<< bad, bad, bad, bad, bad, bad, bad, bad + CategoryInfo : InvalidData: (:) [Foo], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Foo [↓] [vPodans]
На любую попытку обмануть функцию, она ответит вам кучей красного текста (видимо, намекает на кровавую расправу). Теперь, в PowerShell 3.0, эти атрибуты можно использовать не только в секции param() функций, но для любых переменных в консоли:
[↓] [vPodans] [ValidateRange(1,10)][int]$x = 1 [↓] [vPodans] $x = 11 The variable cannot be validated because the value 11 is not a valid value for the x variable. At line:1 char:1 + $x = 11 + ~~~~~~~ + CategoryInfo : MetadataError: (:) [], ValidationMetadataException + FullyQualifiedErrorId : ValidateSetFailure [↓] [vPodans]
И последнее про атрибуты. Для булевых атрибутов теперь не обязательно указывать $true, например:
function Foo { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline)] [int]$a ) process {$a} }
На сегодня это всё.
Всем желающим уже давно доступна для скачивания клиентская версия Windows 8 (Windows Developer Preview downloads), а подписчикам MSDN доступна и серверная версия — Windows Server 8. Я не буду говорить про все новшества новых систем, потому что мой бложек не выдержит столько ненависти в адрес Microsoft. Но как минимум одна вещь доставляет позитива — Windows PowerShell 3.0 и модули.
Возьмём некоторый типовой Windows Server 2008 R2 и посмотрим на встроенные модули, которые доступны «искаропки»:
PS C:\> (Get-Module -ListAvailable).Count 7 PS C:\> Get-Module -ListAvailable ModuleType Name ExportedCommands ---------- ---- ---------------- Manifest ADRMS {} Manifest AppLocker {} Manifest BestPractices {} Manifest BitsTransfer {} Manifest PSDiagnostics {} Manifest ServerManager {} Manifest TroubleshootingPack {} PS C:\>
совсем не густо — только 7 штук. А вот список модулей в Windows Server 8:
PS C:\> (Get-Module -ListAvailable).Count 62 PS C:\> Get-Module -ListAvailable Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules ModuleType Name ExportedCommands ---------- ---- ---------------- Manifest ActiveDirectory {Get-ADRootDSE, New-ADObject, Rename-ADObject, Move-ADObject...} Manifest ADDeploymentWF Invoke-ADCommand Manifest ADDSDeployment {Add-ADDSReadOnlyDomainControllerAccount, Install-ADDSForest, Install-AD... Manifest AppLocker {Set-AppLockerPolicy, Get-AppLockerPolicy, Test-AppLockerPolicy, Get-App... Manifest Appx {Add-AppxPackage, Get-AppxPackageManifest, Get-AppxPackage, Remove-AppxP... Manifest BestPractices {Get-BpaModel, Invoke-BpaModel, Get-BpaResult, Set-BpaResult} Manifest BitsTransfer {Add-BitsFile, Remove-BitsTransfer, Complete-BitsTransfer, Get-BitsTrans... Manifest BranchCache {Add-BCDataCacheExtension, Clear-BCCache, Disable-BC, Disable-BCDowngrad... Manifest CertificateServicesCmd... {Get-AdcsCertificationAuthorityConfigurationDefaults, Get-AdcsConfigurat... Manifest CimCmdlets {Get-CimInstance, Get-CimSession, New-CimSession, New-CimSessionOption...} Manifest ClusterAwareUpdating {Get-CauPlugin, Register-CauPlugin, Unregister-CauPlugin, Invoke-CauScan... Manifest DirectAccessClientComp... {Get-DASiteTableEntry, Set-DASiteTableEntry, Remove-DASiteTableEntry, Re... Manifest Dism Apply-Unattend Manifest DnsClient {Resolve-DnsName, Get-DNSClient, Set-DNSClient, Get-DNSClientCache...} Manifest DnsConfig {Get-DNSClient, Set-DNSClient, Get-DNSClientCache, Clear-DNSClientCache...} Binary DnsLookup Resolve-DnsName Manifest DnsNrpt {Get-DnsClientEffectiveNrptPolicy, Get-DnsClientNrptGlobal, Set-DnsClien... Manifest DnsServer {Clear-DnsServerCache, Get-DnsServerCache, Set-DnsServerCache, Show-DnsS... Manifest FailoverClusters {Add-ClusterCheckpoint, Add-ClusterDisk, Add-ClusterFileServerRole, Add-... Manifest FileServer {Get-SmbShareWF, Get-FsrmQuotaWF, Get-IscsiServerTargetWF, Get-IscsiVirt... Manifest GroupPolicy {Backup-GPO, Copy-GPO, Get-GPInheritance, Get-GPO...} Manifest iSCSI {Connect-iSCSIDiscoveredTarget, Disconnect-iSCSIDiscoveredTarget, Get-iS... Manifest KdsCmdlets {Get-KdsRootKey, Add-KdsRootKey, Test-KdsRootKey, Get-KdsConfiguration...} Manifest Microsoft.PowerShell.Core {Get-Command, Get-Help, Update-Help, Save-Help...} Manifest Microsoft.PowerShell.D... {Get-WinEvent, Get-Counter, Import-Counter, Export-Counter...} Manifest Microsoft.PowerShell.Host {Start-Transcript, Stop-Transcript} Manifest Microsoft.PowerShell.M... {Add-Content, Clear-Content, Clear-ItemProperty, Join-Path...} Manifest Microsoft.PowerShell.S... {Get-Acl, Set-Acl, Get-PfxCertificate, Get-Credential...} Manifest Microsoft.PowerShell.U... {Format-List, Format-Custom, Format-Table, Format-Wide...} Manifest Microsoft.WSMan.Manage... {Disable-WSManCredSSP, Enable-WSManCredSSP, Get-WSManCredSSP, Set-WSManQ... Manifest MicrosoftiSCSITarget {Add-IscsiVirtualDiskTargetMapping, Checkpoint-IscsiVirtualDisk, Dismoun... Manifest MsDtc {New-DtcDiagnosticTransaction, Complete-DtcDiagnosticTransaction, Join-D... Manifest NetAdapter {Rename-NetAdapter, Set-NetAdapter, Get-NetAdapter, Enable-NetAdapter...} Manifest NetLbfo {Get-NetLbfoTeam, Remove-NetLbfoTeam, Set-NetLbfoTeam, New-NetLbfoTeam...} Manifest NetQos {Get-NetQosPolicy, Set-NetQosPolicy, Remove-NetQosPolicy, New-NetQosPolicy} Manifest NetSwitchTeam {Get-NetSwitchTeam, Remove-NetSwitchTeam, New-NetSwitchTeam, Rename-NetS... Manifest NetTCPIP {Get-NetIPAddress, Set-NetIPAddress, Remove-NetIPAddress, New-NetIPAddre... Manifest netwnv {New-NetVirtualizationAddress, Get-NetVirtualizationAddress, Remove-NetV... Manifest NetworkConnectivityStatus {Get-DAConnectionStatus, Get-NCSIPolicyConfiguration, Set-NCSIPolicyConf... Manifest NetworkSecurity {New-NetAuthenticationProposal, New-NetMainModeCryptoProposal, New-NetQu... Manifest NetworkTransition {Get-Net6to4Configuration, Set-Net6to4Configuration, Reset-Net6to4Config... Script PKI Manifest PKIClient {Get-AutoEnrollmentPolicy, Set-AutoEnrollmentPolicy, Export-Certificate,... Manifest PrintManagement {Get-Printer, Remove-Printer, Set-Printer, Add-Printer...} Manifest PS_MMAgent {Disable-MMAgent, Enable-MMAgent, Set-MMAgent} Manifest PSDiagnostics {Start-Trace, Stop-Trace, Enable-WSManTrace, Disable-WSManTrace...} Manifest PSScheduledJob {New-JobTrigger, Add-JobTrigger, Remove-JobTrigger, Get-JobTrigger...} Manifest PSWorkflow {Import-PSWorkflow, New-PSWorkflowExecutionOption} Manifest RDManagement {Grant-OrgUnitAccess, Test-OrgUnitAccess, Restart-ComputersAndBlock, Exp... Manifest ScheduledTasks {New-JobTrigger, Add-JobTrigger, Remove-JobTrigger, Get-JobTrigger...} Manifest SecureBoot {Confirm-SecureBootUEFI, Set-SecureBootUEFI, Get-SecureBootUEFI, Format-... Manifest ServerManager {Add-WindowsFeature, Remove-WindowsFeature} Manifest ServerManagerShell {WFAddRemoveServerComponentAsync, WFGetAlterationState, WFGetGuid, WFGet... Manifest SmbShare {Get-SmbShare, Remove-SmbShare, Set-SmbShare, Block-SmbShareAccess...} Manifest SmbWitness {Get-SmbWitnessCluster, Get-SmbWitnessClusterClient, Move-SmbWitnessClus... Manifest Storage {Add-InitiatorIdToMaskingSet, Add-PartitionAccessPath, Add-PhysicalDisk,... Manifest TelemetryManagement {Set-CEIP, Set-WER} Manifest TroubleshootingPack {Get-TroubleshootingPack, Invoke-TroubleshootingPack} Manifest TrustedPlatformModule {Get-Tpm, Initialize-Tpm, Clear-Tpm, Unblock-Tpm...} Manifest UserAccessLogging {Enable-Ual, Disable-Ual, Get-Ual, Get-UalDhcp...} Manifest Wdac {Get-OdbcDriver, Set-OdbcDriver, Get-OdbcDsn, Add-OdbcDsn...} Manifest Whea {Get-WheaMemoryPolicy, Set-WheaMemoryPolicy} PS C:\>
61 модуль!!!!1111одинодин (мой PKI модуль не в счёт). И это не считая тех, которые устанавливаются вместе с ролями сервера (как, например, модуль ServerBackup). Конкретно сейчас говорить об их возможностях ещё рано, потому что они функционально пока не готовы. Но мы можем представить себе, что это всё дружно заработает ближе к RTM. Из наиболее интересных вещей хочется обрать внимание на вот какие модули:
PS C:\> gcm -Module smbshare | select name Name ---- Block-SmbShareAccess Close-SmbOpenFile Close-SmbSession Get-SmbClientConfiguration Get-SmbClientNetworkInterface Get-SmbConnection Get-SmbConnectionNetworkInterface Get-SmbOpenFile Get-SmbServerConfiguration Get-SmbServerNetworkInterface Get-SmbSession Get-SmbShare Get-SmbShareAccess Grant-SmbShareAccess New-SmbConnection New-SmbShare Remove-SmbConnection Remove-SmbShare Revoke-SmbShareAccess Set-SmbClientConfiguration Set-SmbServerConfiguration Set-SmbShare Unblock-SmbShareAccess
что сильно намекает на то, что мой модуль ShareUtils прожил яркую, но короткую жизнь. Начиная с релиза Windows 8 проку от него особо не будет.
ВНЕЗАПНО!!! Команда пкитима (Windows PKI team), издавна прославляющая религиозно правильный certutil.exe и люто-бешено отрицающая PowerShell снизошла до того, чтобы доставить и свои (поверьте, он там не один!) модули в Windows 8. Или, как вариант, получили хороший нагоняй от Джефри Сновера. Windows PKI представлен двумя модулями — клиентским и серверным. Клиентский модуль представлен следующими командами:
PS C:\> gcm -Module pkiclient | select name Name ---- Add-EnrollmentPolicyServer Export-Certificate Export-PfxCertificate Get-AutoEnrollmentPolicy Get-Certificate Get-CertificateNotificationTask Get-EnrollmentPolicyServer Get-PfxData Import-Certificate Import-PfxCertificate New-CertificateNotificationTask New-SelfSignedCertificate Remove-CertificateNotificationTask Remove-EnrollmentPolicyServer Set-AutoEnrollmentPolicy Switch-Certificate Test-Certificate
Поскольку я немного разбираюсь в PKI и PowerShell, состав этого модуля меня несколько смутил, удивил, оздачил, загнал в тупик. Например, зачем было делать 2 отдельных командлета для экспорта и импорта сертификатов (один для простых сертификатов, другой исключительно для pkcs#12). Что делает Switch-Certificate для меня осталось загадкой. Кстати говоря, командлет Get-Certificate делает совсем не то, что вы подумали. Этот командлет выполняет энроллмент (запрос) сертификата. Всё-таки:
PS C:\> Get-Verb request Verb Group ---- ----- Request Lifecycle
Вобщем, на текущий момент модуль радует, но не впечатляет (если что, я вам не говорил, что 70% функционала модуля не работает вообще).
Серверный модуль предназначен для управления службами сертификатов — Active Directory Certificate Services (ADCS). Когда я увидел модуль, чуть не описался от радости. Но заглянув в модуль моё лицо изобразило очень сложное выражение, похожее на постиранную радугу. Я не знаю, как выглядит постиранная радуга, но выглядит модуль примерно так:
PS C:\> gcm -Module CertificateServicesCmdlets | select name Name ---- Get-AdcsCertificationAuthorityConfigurationDefaults Get-AdcsConfigurationState Get-AdcsEnrollmentPolicyWebServiceConfigurationDefaults Get-AdcsEnrollmentWebServiceConfigurationDefaults Get-AdcsNetworkDeviceEnrollmentConfigurationDefaults Get-SSLCertificates Import-AdcsCertificationAuthorityCACertificatePfx Install-AdcsCertificationAuthority Install-AdcsEnrollmentPolicyWebService Install-AdcsEnrollmentWebService Install-AdcsNetworkDeviceEnrollmentService Install-AdcsOnlineResponder Install-AdcsWebEnrollment Uninstall-AdcsCertificationAuthority Uninstall-AdcsEnrollmentPolicyWebService Uninstall-AdcsEnrollmentWebService Uninstall-AdcsNetworkDeviceEnrollmentService Uninstall-AdcsOnlineResponder Uninstall-AdcsWebEnrollment
на сегодняшний день ни о каком управлении ADCS говорить не приходится, просто набор командлетов для установки/удаления компонентов ADCS. Однако, на удивление некоторые командлеты продуманы достаточно хорошо и даже работают! Т.е. функционально они будут очень полезны. С другой стороны, они оставили мне место для моего PowerShell PKI модуля. Разочаровывают 3 вещи:
PS C:\> gcm -Module activedirectory -Name *password* | select name Name ---- Add-ADDomainControllerPasswordReplicationPolicy Add-ADFineGrainedPasswordPolicySubject Get-ADAccountResultantPasswordReplicationPolicy Get-ADDefaultDomainPasswordPolicy Get-ADDomainControllerPasswordReplicationPolicy Get-ADDomainControllerPasswordReplicationPolicyUsage Get-ADFineGrainedPasswordPolicy Get-ADFineGrainedPasswordPolicySubject Get-ADUserResultantPasswordPolicy New-ADFineGrainedPasswordPolicy Remove-ADDomainControllerPasswordReplicationPolicy Remove-ADFineGrainedPasswordPolicy Remove-ADFineGrainedPasswordPolicySubject Reset-ADServiceAccountPassword Set-ADAccountPassword Set-ADDefaultDomainPasswordPolicy Set-ADFineGrainedPasswordPolicy
И ни одного алиаса! Пока что Windows PKI впереди на 3 символа:
PS C:\> "Get-ADDomainControllerPasswordReplicationPolicyUsage".length 52 PS C:\> "Get-AdcsEnrollmentPolicyWebServiceConfigurationDefaults".length 55
Но мы поддержим команду Active Directory и обвиним команду Windows PKI в том, что у последних префикс на 2 символа длиннее (AD против ADCS), т.е. в итоге превосходство в 1 символ. Кому же достанется первый приз? :) Но мы поддержим обе команды и узнаем победителя с релизом Windows Server 8 :)
В пост про модули я хочу рассказать и про новую возможность автозавершения команд в PowerShell 3.0: при импорте модуля вы можете набрать Import-Module, нажать <tab> и tab expansion будет автозавершать имена модулей. Т.е. вам достаточно знать 1-2 первые буквы названия модуля и он у вас в кармане ;)
На сегодня всё. В следующий раз я постараюсь рассказать ещё что-нибудь интересное про PowerShell 3.0.