Posts on this page:
Продолжая цикл постов о новых командлетах в PowerShell V2 CTP3 хочу рассказать про несколько командлетов для управлением компьютера как клиента в домене Active Directory или рабочей группе. Отмечу сразу, что эти командлеты не управляют доменом Active Directory, а только компьютером-клиентом домена (не знаю, как по-русски правильно сформулировать мысль). По сути эти командлеты повторяют аналог утилиты netdom.exe и вот их список:
и ещё 2 на закуску:
Ну и как обычно - рассмотрим каждый из них:
1) Add-Computer - добавляет компьютер к домену Active Directory или перемещает компьютер между рабочими группами (Workgroup). Данный командлет содержит следующие параметры и ключи:
Примечание: может показаться, что ключ -Reboot очень полезный, но мне так не кажется. И вот почему. Если командлет сам не перезагружает машину после завершения операции, то это нужно сделать вручную. Но перезагружать машину можно только в случае если всё прошло успешно. Но если по каким-то причинам ожидаемый результат не был достигнут, то компьютер будет перезагружен в пустую. Я на этом не настаиваю, но мне это видится именно так.
Hint: не забывайте, что если указываются позиционные параметры, то их имена указывать не обязательно. Например, ComputerName позиционно является первым параметром и если указывать за командлетом сразу имена компьютеров, то название параметра -ComputerName можно и не указывать.
По умолчанию данный командлет не выводит результат на экран, поэтому для вывода результата исполнения можно использовать ключи -PassThru или -Verbose. Так же командлет имеет такие полезные ключи как -Confirm для ручного подтверждения выполнения операции и -WhatIf для моделирования работы командлета. И несколько примеров использования командлета:
Add-Computer -DomainName contoso.com -Credential (Get-Credential) -OUPath OU=Test,OU="3th floor",DC=Contoso,DC=com -Reboot
Add-Computer -ComputerName (Get-Content Comps.txt) -WorkgroupName MSHome -PassThru
2) Remove-Computer - удаляет компьютер из домена или рабочей группы. Содержит параметры -ComputerName, -Credential (учётные данные пользователя, который имеет право на вывод машины из домена или локального администратора, если компьютер перемещается в рабочих группах), -Reboot, -Confirm, -PassThru и -WhatIf. Правила использования этих параметров и ключей такие же, что и для Add-Computer, но только в контексте удаления, а не ввода машины во что-то. Пример:
Remove-Computer -ComputerName computer1, computer2 -Credential contoso.com\Administrator -PassThru -Reboot - выводит компьютер из домена. Следует учесть, что при выполнении команды будет запрошен пароль учётной записи, указанной в Credential.
Remove-Computer MyComputer - просто удаляет компьютер из рабочей группы (интересно, куда? :-D )
Примечание: ни в коем случае не удаляйте так контроллеры домена. Их сначала нужно понизить до роли рядового сервера командой dcpromo и только потом с помощью UI, netdom или командлета Remove-Computer выводить из домена.
3) Rename-Computer - переименовывает компьютер или компьютеры в рабочей группе или домене Active Directory. Обычно использует следующие параметры:
так же командлет содержит такие ключи как -Confirm, -Reboot и -WhatIf.
Примечание: ни в коем случае не пытайтесь этим командлетом переименовать контроллер домена!
4) Reset-ComputerMachinePassword - сбрасывает пароль учётной записи компьютера в базе Active Directory. Используется только для доменных компьютеров. Данный командлет можно использовать при трудностях аутентификации компьютера в домене или при устаревании пароля. Несколько типичных случаев, когда требуется сброс пароля компьютера - компьютер не аутентифицировался в домене более 30 или 60 дней, в зависимости от настроек домена; компьютер был восстановлен из бэкапа (SystemState), срок которого старше 30 или 60 дней или компьютер был восстановлен из образа без дополнительного восстановления актуального SystemState и другие случаи.. Подробности этой темы выходят за рамки этого поста.
Из актуальных параметров содержит -ComputerName (можно указывать несколько компьютеров. Допускаются FQDN, NetBIOS имена или IP адреса), -Server - имя контроллера домена, который будет производить сброс пароля (не обязательный параметр) и -Credental - имя пользователя, который имеет права сброса паролей указанных компьютеров. Из ключей можно выделить такие как -Confirm и -WhatIf. Общий синтаксис такой:
Reset-ComputerMachinePassword (get-content comp.txt) - переустановит пароль всех компьютеров из списка comp.txt
Reset-ComputerMachinePassword - переустановит пароль текущего компьютера
Reset-ComputerMachinePassword -Server dc1.contoso.com -Credential (Get-Credential) -Confirm - переустановит пароль локального компьютера на контроллере домена с именем DC1 и с вводом альтернативных учётных записей. После запуска потребует подтверждения операции.
5) Test-ComputerSecureChannel - проверяет возможность установки безопасного канала между клиентом и сервером. Работает только в домене и возвращает True или False. Имеет один параметр и ключ:
И содержит дополнительные ключи как -Confirm и -WhatIf.
Я не придумал к какой категории присвоить эти 2 командлета и решил их описать здесь. Кстати, очень удобные командлеты:
6) Restart-Computer и Stop-Computer. Первый командлет перезагружает локальный или удалённый компьютер (или несколько), а второй выключает их совсем. Это очень полезно, поскольку я видел как минимум 5 различных решений перезагрузки/выключения компьютеров в скриптах PowerShell. Как правило это либо WMI, либо использование штатного shutdown.exe (кстати говоря, я им пользуюсь всегда) либо ещё что-нибудь. Теперь можно будет этот момент стандартизировать. Много говорить про них не буду, а скажу только, что эти командлеты используют метод Win32Shutdown WMI класса Win32_OperatingSystem. Следовательно эти командлеты обладают всеми новыми возможностями, которые описаны в предыдущей статье: Обзор новых командлетов PowerShell V2 CTP3 - WMI. Одно из преимуществ - можно использовать фоновую работу. Скажем, отправить в ребут сотню компьютеров и пока это всё происходит спокойно работать в консоли (шутка :-) ). Поэтому в этих командлетах можно использовать такие параметры и ключи как -AsJob, Impersonate, Authentication, ComputerName и другие. Из уникальных отмечу один параметр:
и ключ:
На сегодня вроде всё. Вроде ничего не пропустил.
Windows Management Instrumentarion или просто WMI в PowerShell V2 так же претерпел изменения, а точнее дополнения по сравнению с версией 1.0. Я планирую более подробно описать новые и обновлённые параметры командлета Get-WMIObject:
В версии 2.0 появились командлеты, которые позволяют в однострочном режиме управлять параметрами восстановления системы. В них входят:
Мой вариант костылей для версии 1.0 описан здесь: SystemRestore и PowerShell. По сути в версии 1.0 доступно большинство функционала V2, но только в виде самописных функций, в V2 уже есть всё (или почти всё) в коробке. Для работы этих командлетов так же потребуются клиентские версии ОС Windows XP/Windows Vista. Посмотрим их попорядку:
1) Get-ComputerRestorePoint - получает список доступных точек восстановления.
Get-ComputerRestorePoint 490 - 490 - опциональный параметр, который позволяет получить сведения о конкретной точке восстановления.
[System32] Get-ComputerRestorePoint
CreationTime Description SequenceNumber EventType RestorePointType
------------ ----------- -------------- --------- ----------------
2008.12.29. 21:14:04 Windows Installer installed... 490 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2008.12.29. 21:56:01 Windows Update 491 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2008.12.29. 21:58:55 Windows Update 492 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2008.12.31. 1:38:08 Windows Update 493 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2009.01.01. 21:53:49 Windows Installer installed... 494 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2009.01.01. 22:03:01 Windows Installer installed... 495 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2009.01.02. 1:38:06 Windows Update 496 BEGIN_SYSTEM_C... APPLICATION_INSTALL
2009.01.02. 19:45:27 Windows Installer installed... 497 BEGIN_SYSTEM_C... APPLICATION_INSTALL
[System32] Get-ComputerRestorePoint 490 | select *
__GENUS : 2
__CLASS : SystemRestore
__SUPERCLASS :
__DYNASTY : SystemRestore
__RELPATH : SystemRestore.SequenceNumber=490
__PROPERTY_COUNT : 5
__DERIVATION : {}
__SERVER : THOR
__NAMESPACE : root\default
__PATH : \\THOR\root\default:SystemRestore.SequenceNumber=490
CreationTime : 20081229191404.400068-000
Description : Windows Installer installed Quest PowerGUI 1.5.3.
EventType : 100
RestorePointType : 0
SequenceNumber : 490
Scope : System.Management.ManagementScope
Path : \\THOR\root\default:SystemRestore.SequenceNumber=490
Options : System.Management.ObjectGetOptions
ClassPath : \\THOR\root\default:SystemRestore
Properties : {CreationTime, Description, EventType, RestorePointType...}
SystemProperties : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}
Qualifiers : {dynamic}
Site :
Container :
[System32]
Если посмотреть внимательней, то можно легко заметить, что данный командлет (как и все остальные, которые относятся к SystemRestore) реализован через тот же WMI класс SystemRestore. Поэтому на эти командлеты будут накладываться ограничения, которые накладывает этот класс. Это и версия ОС и права доступа. В данном случае для работы с командлетами восстановления системы нужны права администратора и для Windows Vista - проход запроса UAC.
2) Checkpoint-Computer - создаёт новую точку восстановления. Синтаксис командлета может быть такой:
Checkpoint-Computer -RestorePointType Application_Install -Description CustomDescription
-RestorePointType может иметь следующие значения:
-Description может иметь любое значение, поскольку это будет всего лишь описание. Но лучше использовать рекомендованные значения для описаний, которые документированы в статье MSDN: Restore Point Description Text. Стандартизация в наше время - это очень важно. Время создания точки восстановления на моём нотебуке составило чуть больше минуты и на экране консоли будет такой псевдографический прогресс-бар:
я вот тоже хочу как-нибудь научиться делать такие прогресс-бары.
3) Restore-Computer - восстанавливает компьютер до указанной точки восстановления:
Restore-Computer -RestorePoint 490 -Confirm -WhatIf
в параметре -RestorePoint указывается номер точки восстановления, который можно получить командой Get-ComputerRestorePoint. Данный командлет обладает ещё опциональными параметрами -Confirm, который будет требовать подтверждения пользователя и -WhatIf, который будет полезен в отладочных целях.
Примечание: после успешного выполнения данной команды компьютер будет перезагружен в обязательном порядке для завершения восстановления.
4) Enable-ComputerRestore - включает режим восстановления системы для всех дисков или для определённых.
Enable-ComputerRestore -Drive "C:\" -WhatIf
Параметры -Drive и -WhatIf являются не обязательными. Если не указан -Drive, то восстановление системы будет включено для всех допустимых дисков в системе.
5) Disable-ComputerRestore - отключает режим восстановления системы для всех дисков или определеённых:
Disable-ComputerRestore -Drive "C:\" -WhatIf
Параметры -Drive и -WhatIf являются не обязательными. Если не указан -Drive, то восстановление системы будет отключено для всех дисков в системе.
К сожалению функционал изменения настроек SystemRestore, как резервирование места для точек восстановления, время хранения, периодичность создания точек не реализован в командлетах. А ведь лишним это не будет однозначно. Поэтому в отношении CTP3 эти вещи придётся реализовывать с помощью WMI самостоятельно.
PowerShell V2 CTP3 вышел уже давно (23 декабря прошлого года), но всё никак не доходили руки осветить новые командлеты. Сегодня постараюсь рассказать о новых возможностях работы с журналами событий готовыми командлетами. Функционал этих командлетов я уже реализовывал немного раньше:
Но плюс новых командлетов в том, что это уже готовые командлеты, а не костыли в виде отдельных функций. Безусловно, ещё не всё работает как положено, но обзор уже делать можно. Итак, список командлетов:
начнём попорядку:
1) Get-WinEvent. Данный командлет призван заменить ранее использовавшийся командлет Get-Eventlog. Синтаксис команды может быть следующий:
[System32] Get-WinEvent -ListLog * | ft -a
LogName MaximumSizeInBytes RecordCount LogMode
------- ------------------ ----------- -------
Application 20971520 17003 Circular
DFS Replication 15532032 6 Circular
HardwareEvents 20971520 0 Circular
Internet Explorer 1052672 0 Circular
Key Management Service 20971520 0 Circular
ODiag 16777216 267 Circular
OSession 16777216 544 Circular
Security 33554432 16904 Circular
System 20971520 43146 Circular
Windows PowerShell 15728640 16803 Circular
ForwardedEvents 20971520 Circular
Microsoft-Windows-Backup 1052672 6 Circular
Microsoft-Windows-Bits-Client/Analytic 1052672 Circular
Microsoft-Windows-Bits-Client/Operational 1052672 2226 Circular
....
Показ всех журналов событий в системе, включая журналы в Application and Services Logs (для Vista/2008). Вместо звёздочки можно указать конкретный журнал событий.
Примечание: некоторые журналы, как Security будут генерировать ошибку, если вы исполняете эту команду под обычным пользователем.
Последняя колонка показывает режим очистки журнала. Circular означает перезапись более старых событий по мере необходимости. Так же можно посмотреть список провайдеров, которые регистрируют события в журнале:
[System32] Get-WinEvent -ListProvider *
Name LogLinks
---- --------
.NET Runtime {Application}
.NET Runtime Optimization Service {Application}
Active Server Pages {Application}
Application {Application}
Application Error {Application}
Application Hang {Application}
Application Management {Application}
ASP.NET 1.1.4322.0 {Application}
ASP.NET 2.0.50727.0 {Application}
CardSpace 3.0.0.0 {Application}
Chkdsk {Application}
Crystal Reports {Application}
DataDynamics ActiveBar 1.0 {Application}
Desktop Window Manager {Application}
devenv {Application}
....
Вот образец провайдеров. Это может быть очень удобным, когда вам нужна выборка именно логов конкретного провайдера. Делается это следующей командой:
Get-WinEvent -ProviderName "Application Hang"
В кавычках просто указываете поставщика событий. Сами события можно посмотреть следующим образом:
[System32] Get-WinEvent -ProviderName "Application Hang" -MaxEvents 1 | select *
Message :
Id : 1002
Version :
Qualifiers : 0
Level : 2
Task : 101
Opcode :
Keywords : 36028797018963968
RecordId : 16431
ProviderName : Application Hang
ProviderId :
LogName : Application
ProcessId :
ThreadId :
MachineName : Thor
UserId :
TimeCreated : 2008.12.21. 17:19:47
ActivityId :
RelatedActivityId :
ContainerLog : application
MatchedQueryIds : {}
Bookmark : System.Diagnostics.Eventing.Reader.EventBookmark
LevelDisplayName :
OpcodeDisplayName :
TaskDisplayName :
KeywordsDisplayNames : {}
Properties : {System.Diagnostics.Eventing.Reader.EventProperty, System.Diagnostics.Eventing.Reader.EventPrope
rty, System.Diagnostics.Eventing.Reader.EventProperty, System.Diagnostics.Eventing.Reader.EventP
roperty...}
[System32]
вот так выглядят внутренности события. Однако, свойство Message ничего не содержит, хотя предполагается, что там должен быть текст самого эвента. Пустое оно потому что:
[System32] Get-WinEvent -ProviderName "Application Hang" -MaxEvents 1 | gm -MemberType noteproperty
TypeName: System.Diagnostics.Eventing.Reader.EventLogRecord
Name MemberType Definition
---- ---------- ----------
Message NoteProperty Message=null
[System32]
в членах объекта мы видим, что свойство Message заткнуто заглушкой (Message=null) и оно ничего не возвращает. Но текст события можно извлечь из свойства Properties:
[System32] (Get-WinEvent -ProviderName "Application Hang" -MaxEvents 1).properties
Value
-----
mstsc.exe
6.0.6002.18000
ac0
01c9637bc8453f5e
8
{67, 0, 114, 0...}
[System32]
текст тут невнятный совсем. Для некоторых событий он возвращает такой же текст, что и в графическом журнале событий (и которые корректно отображаются командлетом Get-EventLog). Те события, которые не показывает корректно Get-EventLog в новом командлете уже не показывают ничего. Тут вся надежда на разработчиков, что они наконец-то сделают возможность полностью видеть тексты всех эвентов журнала событий, в противном случае придётся снова забивать костыли с помощью адского WMI. Но тут следует обратить внимание на параметр MaxEvents. Без его указания поиск только нескольких событий (например, первых 10 с использованием Select -First 10) займёт значительное время, поскольку команда будет работать пока весь журнал не будет прочёсан. Этот параметр является аналогом параметра -Newest для Get-EventLog. Поэтому если вы хотите посмотреть только часть событий, то используйте этот параметр. В общем смысле это выглядит так:
И ещё одно хорошее отличие нового командлета - теперь не обязательно указывать журнал для поиска. Вы можете указать только поставщика событий и количество событий для вывода. Это очень удобно.
Следовательно можно судить, что новый командлет Get-WinEvent является значимо более лучшим, чем прежний Get-EventLog. Хотя его применимость в настоящее время весьма сомнительна, поскольку работу с текстом событий так никто и не сделал.
2) New-EventLog. Нетрудно догадаться, что этот командлет создаёт новый журнал событий:
New-EventLog -LogName "Custom EventLog" -Source "Custom Source"
[System32] New-EventLog -LogName "Custom EventLog" -Source "Custom Source"
[System32] Get-EventLog -List
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
20 480 0 OverwriteAsNeeded 17 011 Application
512 7 OverwriteOlder 0 Custom EventLog
15 168 0 OverwriteAsNeeded 6 DFS Replication
20 480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 0 Internet Explorer
20 480 0 OverwriteAsNeeded 0 Key Management Service
16 384 0 OverwriteAsNeeded 267 ODiag
16 384 0 OverwriteAsNeeded 544 OSession
32 768 0 OverwriteAsNeeded 16 908 Security
20 480 0 OverwriteAsNeeded 43 162 System
15 360 0 OverwriteAsNeeded 16 920 Windows PowerShell
[System32] Get-WinEvent -ListProvider "custom Source"
Name LogLinks
---- --------
Custom Source {Custom EventLog}
[System32]
Всё очень просто. Внизу я сделал проверку, что наш провайдер событий успешно зарегистрировался и он будет писать только в журнал Custom EventLog. Так же можно и добавлять события (поставщиков) к существующим журналам. Для этого в параметре -LogName нужно указать существующий журнал.
3) Write-Eventlog. Так же по смыслу можно догадаться, что данный командлет добавляет записи в журнал событий. Общий синтаксис его такой:
Write-EventLog -LogName "Custom EventLog" -Source "Custom Source" -EntryType Information -EventID 1 -Message "Привет мир!"
EntryType может иметь следующие значения: Error, Warning, Information, SuccessAudit, FailureAudit. Об этом я уже говорил ранее здесь. Смотрим:
[[System32] Write-EventLog -LogName "Custom EventLog" -Source "Custom Source" -EntryType Information -EventID 1 -Message
"Привет мир!"
[System32] Get-WinEvent -ProviderName "Custom source"
TimeCreated ProviderName Id Message
----------- ------------ -- -------
2009.01.02. 21:05:06 Custom Source 1
[System32] Get-WinEvent -ProviderName "Custom source" | select *
Message :
Id : 1
Version :
Qualifiers : 0
Level : 4
Task : 1
Opcode :
Keywords : 36028797018963968
RecordId : 1
ProviderName : Custom Source
ProviderId :
LogName : Custom EventLog
ProcessId :
ThreadId :
MachineName : Thor
UserId :
TimeCreated : 2009.01.02. 21:05:06
ActivityId :
RelatedActivityId :
ContainerLog : custom eventlog
MatchedQueryIds : {}
Bookmark : System.Diagnostics.Eventing.Reader.EventBookmark
LevelDisplayName :
OpcodeDisplayName :
TaskDisplayName :
KeywordsDisplayNames : {}
Properties : {System.Diagnostics.Eventing.Reader.EventProperty}
[System32] (Get-WinEvent -ProviderName "custom source").Properties
Value
-----
Привет мир!
[System32]
Первой строкой мы создали новое событие в журнале, второй посмотрели общую сводку по провайдеру Custom Source, которого мы создали ранее. В нём уже зарегистрировано одно событие, которое мы посмотрели в расширенном виде. И последней строкой посмотрели текст созданного события.
Спросите вы, какая польза от этого, ведь кроме программистов это мало кому нужно? А польза есть от него. Для примера можно взять резервное копирование. Например, у администратор регулярно выполняются скрипты, которые делают резервное копирование данных. И создав нового провайдера или новый журнал администратор может в скрипт добавить код, который будет лог копирования помещать в журнал событий помимо стандартной процедуры отправки лога к себе на почту. Это может оказаться очень удобным! Так же данный командлет содержит параметр -WhatIf, который следует использовать в отладочных целях.
4) Clear-EventLog. Очистка журнала:
Clear-EventLog -LogName "Custom EventLog"
тут всё проще постого. Указываете имя журнала и очищаем его:
[System32] Clear-EventLog "Custom EventLog"
[System32] Get-EventLog -List
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
20 480 0 OverwriteAsNeeded 17 011 Application
512 7 OverwriteOlder 0 Custom EventLog
15 168 0 OverwriteAsNeeded 6 DFS Replication
20 480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 0 Internet Explorer
20 480 0 OverwriteAsNeeded 0 Key Management Service
16 384 0 OverwriteAsNeeded 267 ODiag
16 384 0 OverwriteAsNeeded 544 OSession
32 768 0 OverwriteAsNeeded 16 908 Security
20 480 0 OverwriteAsNeeded 43 165 System
15 360 0 OverwriteAsNeeded 16 920 Windows PowerShell
[System32]
Во второй строчке мы уже видим, что нами созданный журнал очистился от тестового сообщения. Данный командлет содержит параметр -WhatIf, который следует использовать в отладочных целях.
5) Limit-EventLog. Позволяет изменять размер журнала и политику перезаписи журнала. Общий синтаксис такой:
Limit-EventLog -LogName "Custom EventLog" -MaximumSize 64mb -OverflowAction OverWriteOlder -RetentionDays 10
[System32] Limit-EventLog -LogName "Custom EventLog" -MaximumSize 64mb -OverflowAction OverWriteOlder -RetentionDays 10
[System32] Get-EventLog -List
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
20 480 0 OverwriteAsNeeded 17 011 Application
65 536 10 OverwriteOlder 0 Custom EventLog
15 168 0 OverwriteAsNeeded 6 DFS Replication
20 480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 0 Internet Explorer
20 480 0 OverwriteAsNeeded 0 Key Management Service
16 384 0 OverwriteAsNeeded 267 ODiag
16 384 0 OverwriteAsNeeded 544 OSession
32 768 0 OverwriteAsNeeded 16 908 Security
20 480 0 OverwriteAsNeeded 43 165 System
15 360 0 OverwriteAsNeeded 16 920 Windows PowerShell
[System32]
Здесь мы задали размер журнала в 64 мегабайта и политику перезаписи старых логов старше 10 дней.
6) Remove-EventLog. Удаляет журнал событий или провайдера событий:
Remove-EventLog -Source "Custom Source" - удаляет провайдера событий из системы
Remove-EventLog -LogName "Custom EventLog" - удаляет указанный журнал из системы
И этот командлет содержит параметр -WhatIf.
В принципе, есть ещё командлет Remove-Event, который должен позволять удалять события из журналов событий, но мне пока что не удалось заставить его работать. Но вообще удаление эвентов из журналов событий - плохая и порочная практика, которая ни к чему хорошему не приведёт.
Вот мы и рассмотрели все новые командлеты в PowerShell V2 CTP3, которые относятся к работе с журналами событий (эвентлогами). В самом начале поста я привёл ссылки, на альтернативные решения, которые повторяют функционал этих командлетов для версии 1.0, но и даже умеют немножко больше (например, архивация и ротация архивов эвентлогов). В целом можно оценить позитив от новых командлетов, которые позволяют нам более удобным способом работать с журналами событий. Но всё равно нужно ждать рабочего решения, который смог бы получать тексты сообщений из журналов Windows Vista/Windows Server 2008, поскольку без него все эти нововведения мало кому будут нужны. Вобщем, как-то так.
Как и ожидалось - негативные. Я не знаю почему, но я настолько привык к версии 1.0, что V2 уже стал отвергать на подсознательном уровне, отрицая все потенциальные преимущества V2. Да, в 1.0 много чего не было сделано, приходилось конструировать собственные костыли, чтобы получить нужный результат, но 1.0 казался как-то роднее и приятней. Я тянул до последнего и вчера совершил героическое обновление PowerShell 1.0 до V2 CTP3. При этом следовал чётким инструкциям ReleaseNotes - корректно деинсталлировал версию 1.0 и потом установил V2 CTP3. Баг был обнаружен мною уже при втором запуске консоли или через 1 минуту после установки.
Суть проблемы: на своём ноутбуке с Windows Vista SP1 я использую Software Restriction Policies и действие по умолчанию Disallowed. Для необходимых путей добавлены исключения с действием Unrestricted и из стандартного набора удалёно расширение .chm и всё. А к чему я это всё? Вот мой второй запуск консоли PowerShell V2 CTP3 (после возвращения политики SRP в исходное состояние):
Windows PowerShell V2 (Community Technology Preview - Features Subject to Change)
Copyright (C) 2008 Microsoft Corporation. All rights reserved.
File D:\Users\vpodans\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 cannot be loaded because its executi
on is blocked by software restriction policies. For more information, contact your system administrator.
At line:1 char:2
+ . <<<< 'D:\Users\vpodans\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
PS C:\Users\vPodans> Get-ExecutionPolicy
RemoteSigned
PS C:\Users\vPodans>
С dot sourced скриптами дела обстояли так же:
PS C:\Users\vPodans> "Get-Date" | Set-Content -Path .\date.ps1
PS C:\Users\vPodans> Get-Content .\date.ps1
Get-Date
PS C:\Users\vPodans> . .\date.ps1
File C:\Users\vPodans\date.ps1 cannot be loaded because its execution is blocked by software restriction policies. For
more information, contact your system administrator.
At line:1 char:2
+ . <<<< .\date.ps1
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
PS C:\Users\vPodans>
Любые попытки исполнения файлов скриптов завершились ничем. Первым делом я проверил настройки политик SRP и убедился, что расширения PS1 нету. Причём все файлы скриптов замечательно открываются по двойному клику в PowerGUI и в системном журнале Application никаких записей об этом не зарегистрировано. Далее я попробовал включить расширенное логирование работы Software Restriction Policies:
reg.exe add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers" /v LogFileName /d saferlog.txt
и попробовал снова запустить консоль PowerShell. В итоге я получил файл примерно такого содержания:
svchost.exe (PID = 1152) identified C:\Windows\system32\consent.exe as Unrestricted using path rule, Guid = {191cd7fa-f240-4a17-8986-94d480a6c8ca}
svchost.exe (PID = 856) identified C:\Windows\system32\DllHost.exe as Unrestricted using path rule, Guid = {191cd7fa-f240-4a17-8986-94d480a6c8ca}
svchost.exe (PID = 856) identified C:\Windows\system32\DllHost.exe as Unrestricted using path rule, Guid = {191cd7fa-f240-4a17-8986-94d480a6c8ca}
svchost.exe (PID = 1152) identified C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe as Unrestricted using path rule, Guid = {191cd7fa-f240-4a17-8986-94d480a6c8ca}
powershell.exe (PID = 2688) identified D:\Users\Administrator\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 as Disallowed using default rule, Guid = {11015445-d282-4f86-96a2-9e485f593302}
Первой строчкой отображена попытка запуска запуска приложения с повышенными привилегиями. Далее (самая последняя строчка) видно, что файл профиля (Microsoft.PowerShell_profile.ps1) был действительно блокирован политикой. Но на каком основании блокирован и почему нету соответствующей записи в журнале Application мне до сих пор неизвестно. Я так же произвёл аудит доступа к файлу профиля, но там ничего подозрительного не увидел. Вобщем вот такие дела, господа.
Решение: в качестве временного решения в политику SRP было добавлено 2 исключения:
Для этих двух правил уровень нужно выставить Unrestricted. Ради интереса я попробовал выставить уровень Basic User и что интересно - PS1 файлы так же блокируются, как и при отсутствии этих дополнительных исключений!
Я не знаю, что такого там натворили разработчики PowerShell в CTP3 (я не знаю, была ли такая проблема в более ранних CTP версиях или нет), но мне кажется тут попахивает не просто какой-то ошибкой в коде, а нечто более глобальным, что загрузка PS1 файлов каким-то образом ловится и отшивается политиками Software Restriction Policies. Заодно можно посетовать на практически отсутствующие инструменты отслеживания работы политик SRP :( (расширенное логирование не сильно помогает в этом деле). Если у кого-то есть возможность повторить ситуацию (работа PowerShell V2 CTP3 с работающей политикой SRP), то отпишитесь в комментах о результатах. Если данный баг подтвердится, то не забудьте подтвердить его здесь:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=389878&SiteID=99