Posts on this page:
2 недели назад я выступал на рижском IT Pro с темой бэкапа в Windows Server 2008 R2 с помощью PowerShell. Доклад получится немного скомканный и на ряд вопров из зала я не смог ответить, т.к. эти вопросы требуют достаточно много времени на формулировку ответа. Поэтому я здесь подниму этот вопрос снова и постараюсь ответить на неотвеченные вопросы.
Я думаю, что уже все знают про отсутствие ntbackup.exe в системах начиная с Windows Server 2008. Его теперь заменяет отдельный системный компонент Windows Backup (или Server Backup) и, который, устанавливается как компонент сервера в оснастке Server Manager. Первая версия Server Backup была достаточно грубой и примитивной. Она позволяла бэкапить только тома целиком блочным методом без возможности выбора отдельных файлов и папок. Блочный метод работает на уровень ниже, чем файловая система, поэтому никакой речи о файлах быть не могло. Так же ему требовался выделенный том под хранение бэкапа и при инициализации тома под бэкапы, он форматировался. Бэкап SystemState производился отдельно и его нельзя было включить в состав бэкапа отдельного тома. Иными словами, первая версия была непотребна чуть более чем полностью, поэтому в отношении него говорить просто не о чем.
С выходом Windows Server 2008 R2 ситуация немного улучшилась. После тысяч жалоб от покупателей и срачей на форумах в новой системе добавился бэкап на уровне файловой системы (как и ntbackup), сохранив и улучшив первоначальную версию Server Backup. Новая версия бэкапа отличается следующими характеристиками по сравнению с первой версией:
Как и раньше, командлеты для Server Backup поставляются в виде отдельной оснастки, которая подключается командой:
Add-PSSnapin Windows.ServerBackup
И все командлеты для бэкапа будут иметь префикс WB (от Windows Backup):
Мы видим достаточно приличное количество командлетов и часть из них мы используем для работы. Все задания бэкапов в ServerBackup являются политиками бэкапа. Следовательно, командлетом New-WBPolicy мы будем создавать каждое задание бэкапа:
[↑] [Administrator] $pol = New-WBPolicy [↑] [Administrator] $pol Schedule : BackupTargets : VolumesToBackup : FilesSpecsToBackup : FilesSpecsToExclude : BMR : False SystemState : False VssBackupOptions : VssCopyBackup [↑] [Administrator]
Мы создали объект новой политики бэкапа, который имеет ряд свойств. Эти свойства по названиям уже отражают своё назначение. Давайте сначала выберем объекты бэкапа. Например, добавим какую-нибудь папку, которую мы захотим бэкапить. Новые объекты бэкапа создаются в 2 этапа:
Будь то отдельная папка или отдельный том. Это не относится только к Bare Metal Recovery (полный бэкап системного тома, SystemState и всех системных файлов) и к самому SystemState. Они могут сразу добавляться в политику.
[↑] [Administrator] $source1 = New-WBFileSpec -FileSpec "C:\Users" [↑] [Administrator] $source1 | ft -a FilePath FileName IsRecursive IsIncludeSpec -------- -------- ----------- ------------- C:\Users\ * True True [↑] [Administrator] $exclusion = New-WBFileSpec -FileSpec "C:\Users\vpodans" -Exclude [↑] [Administrator] $exclusion | ft -a FilePath FileName IsRecursive IsIncludeSpec -------- -------- ----------- ------------- C:\Users\vpodans\ * True False [↑] [Administrator] $source2 = New-WBFileSpec -FileSpec "D:\Users" -NonRecursive [↑] [Administrator] $source2 | ft -a FilePath FileName IsRecursive IsIncludeSpec -------- -------- ----------- ------------- D:\Users\ * False True [↑] [Administrator] $source1, $source2, $exclusion | Add-WBFileSpec -Policy $pol [↑] [Administrator] $pol Schedule : BackupTargets : VolumesToBackup : FilesSpecsToBackup : {C:\Users\*, D:\Users\*} FilesSpecsToExclude : {C:\Users\vpodans\*} BMR : False SystemState : False VssBackupOptions : VssCopyBackup [↑] [Administrator]
Первой командой мы задали бэкап всей папки C:\Users. Второй командой мы посмотрели объект этой точки. Как видно из таблички, эта папка будет бэкапить полностью включая все подпапки. Но я не хочу бэкапить папку профиля одного из пользователей. Для этого в командлете New-WBFileSpec есть ключ –Exclude, который исключит эту папку из бэкапа. В следующей строке это видно по состоянию свойства IsIncludeSpec = $false. И чтобы исключить рекурсивную обработку папки (т.е. нам нужно бэкапить содержимое только текущей папки не трогая подпапки совсем) для неё достаточно указать ключ –NonRecursive. под каждую категорию вы можете добавлять пути для бэкапа через запятую в одной команде. Но для каждой категории надо писать новую команду. В конце мы видим, что наша политика уже обросла какими-то данными. Если мы захотим сюда добавить ещё бэкап целого тома или физического диска, то нам уже придётся работать с командлетами Get/Add-WBDisk и Get/Add-WBVolume:
[↑] [Administrator] Get-WBDisk DiskName : WDC WD3200JS-00PDB0 ATA Device DiskNumber : 1 DiskId : d5fae841-0000-0000-0000-000000000000 TotalSpace : 320072933376 FreeSpace : 3591163904 Volumes : {New Volume (S:\VM\Core), Camelot Share-2 (F:)} ContainsBackup : False BackupVolumeId : 00000000-0000-0000-0000-000000000000 Properties : Dynamic, ValidTarget <...> [↑] [Administrator] $disk = Get-WBDisk | ?{$_.disknumber -eq 1} [↑] [Administrator] Get-WBVolume -Disk $disk VolumeLabel : New Volume MountPath : S:\VM\Core MountPoint : \\?\Volume{06d04bb0-1949-11de-a731-001fd08fc2f1} FileSystem : NTFS Property : ValidSource FreeSpace : 2133585920 TotalSpace : 18875416576 VolumeLabel : Camelot Share-2 MountPath : F: MountPoint : \\?\Volume{62bda1e6-b515-4102-b03f-40b7896ab0f3} FileSystem : NTFS Property : ValidSource FreeSpace : 1453031424 TotalSpace : 301192970240 [↑] [Administrator]
Командлет Get-WBDisk отобразит нам все физические диски, которые подключены к системе (с учётом аппаратного рейда, разумеется). Если захотим добавить этот диск в бэкап, то отфильтровываем через Where-Object (или просто вопросительный знак) и добавляем его в политику командой Add-WBDisk. Get-WBDisk нам так же потребуется и для просмотра логических томов, поскольку Get-WBVolume в качестве аргумента принимает только объекты, полученные от команды Get-WBDisk. Т.е. сначала выбираем диск и только потом просматриваем нужные тома. И отфильтровав нужный том добавляем в политику, например:
[↑] [Administrator] Get-WBVolume -Disk $disk VolumeLabel : New Volume MountPath : S:\VM\Core MountPoint : \\?\Volume{06d04bb0-1949-11de-a731-001fd08fc2f1} FileSystem : NTFS Property : ValidSource FreeSpace : 2133585920 TotalSpace : 18875416576 VolumeLabel : Camelot Share-2 MountPath : F: MountPoint : \\?\Volume{62bda1e6-b515-4102-b03f-40b7896ab0f3} FileSystem : NTFS Property : ValidSource FreeSpace : 1453031424 TotalSpace : 301192970240 [↑] [Administrator] $volume = Get-WBVolume -Disk $disk | ?{$_.volumelabel -eq "new volume"} [↑] [Administrator] Add-WBVolume -Policy $pol -Volume $volume VolumeLabel : New Volume MountPath : S:\VM\Core MountPoint : \\?\Volume{06d04bb0-1949-11de-a731-001fd08fc2f1} FileSystem : NTFS Property : ValidSource FreeSpace : 2133585920 TotalSpace : 18875416576 [↑] [Administrator] $pol Schedule : BackupTargets : VolumesToBackup : {New Volume (S:\VM\Core)} FilesSpecsToBackup : {C:\Users\*, D:\Users\*} FilesSpecsToExclude : {C:\Users\vpodans\*} BMR : False SystemState : False VssBackupOptions : VssCopyBackup [↑] [Administrator]
Если я вдруг не захочу уже бэкапить добавленный том, то его можно спокойно удалить (фактически командами Remove-WB* можно удалить что угодной из политики):
Remove-WBVolume -Policy $pol -Volume $volume
Теперь настало время выбрать точки, в которые мы будем копировать наш бэкап. Точки назначения добавляются в бэкап тоже задаются в 2 этапа:
[↑] [Administrator] $target = New-WBBackupTarget -VolumePath "F:" [↑] [Administrator] $target = New-WBBackupTarget -VolumePath "E:" [↑] [Administrator] Add-WBBackupTarget -Policy $pol -Target $target Label : Camelot Share-1 WBDisk : WBVolume : Camelot Share-1 (E:) Path : \\?\Volume{ca6dbf07-14ad-11de-937f-806e6f6e6963} TargetType : Volume InheritAcl : False PreserveExistingBackup : False [↑] [Administrator] $pol Schedule : BackupTargets : {E:} VolumesToBackup : {} FilesSpecsToBackup : {C:\Users\*, D:\Users\*} FilesSpecsToExclude : {C:\Users\vpodans\*} BMR : False SystemState : False VssBackupOptions : VssCopyBackup [↑] [Administrator]
Вы так же можете указать бэкап сразу в сеть. Для этого в команде New-WBBackupTarget вместо параметра –VolumePath использовать параметр –NetworkPath и за ним уже указывать UNC путь к сетевой папке. Однако, следует учесть несколько нюансов:
Примечание: хелп заявляет, что бэкап можно одновременно копировать на несколько томов/дисков. Мне ещё неизвестна полностью природа всего происходящего и только могу констатировать факт, что физически бэкап копируется только на первый указанный том или диск.
Теперь у нас есть 2 варианта: начать выполнение бэкапа немедленно, или регистрация нашей политике в системе для периодического выполнения в автоматическом режиме (по внутреннему шедулеру). В первом случае достаточно выполнить команду:
Start-WBBackup –Policy $pol
или зашедулить командой Set-WBSchedule:
[↑] [Administrator] Set-WBSchedule -Policy $pol -Schedule "10.08.2009 21:00" tresdiena, 2009. gada 7. oktobri 21:00:00 [↑] [Administrator] $pol Schedule : {2009.10.07. 21:00:00} BackupTargets : {E:} VolumesToBackup : {} FilesSpecsToBackup : {C:\Users\*, D:\Users\*} FilesSpecsToExclude : {C:\Users\vpodans\*} BMR : False SystemState : False VssBackupOptions : VssCopyBackup [↑] [Administrator] Set-WBPolicy –Policy $pol
И командой Set-WBPolicy наша политика регистрируется в системе. Шедулинг следует указывать в следующей форме:
Month.Day.Year Hours:Minutes
И теперь каждый день в 21:00 будет выполняться наше задание.
Сегодня мы рассмотрели основные моменты создания политики бэкапа в Windows Server 2008 R2 с использованием PowerShell. В следующей (или следующих) рассмотрим вопросы управления этими политиками и вопросы каталогизации/ротации архивов.
А знаете ли вы как можно легко получить список всех Enterprise CA в текущем домене? А в текущем лесу? Оказывается это очень легко! ADSI — самый лучший способ, если вы хотите пошариться в своей базе AD. Список таких CA находится по пути:
CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=Domain, DC=COM
Последние 2 значения уже будут отличаться в зависимости от имени домена. Чтобы получить список объектов по этому пути нужно просто создать соответствующий LDAP объект. Объект делается просто, сначала указывается тип объекта [ADSI], следом идёт префикс ссылки LDAP:// (почти как HTTP://) и после префикса уже этот путь (который называется Distinguished Name или просто DN):
[Administrator] $CA = [ADSI]"LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=co ntoso,DC=COM" [Administrator] $CA distinguishedName : {CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com} Path : LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=contoso,DC =COM [Administrator] $CA.distinguishedName CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com
Если посмотреть этот путь в ADSIEdit.msc, то мы увидим, что это контейнер. А раз это контейнер, то нам нужно в него заглянуть. Здесь, к сожалению, нельзя сделать dir $CA.distinguishedName, а так хочется. Чтобы посмотреть содержимое нужно использовать свойство Children (ворненк, дети отаке!):
[Administrator] $ca.Children distinguishedName : {CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=co ntoso,DC=com} Path : LDAP://CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services, CN=Services, CN=Configurati on, DC=contoso,DC=COM distinguishedName : {CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contos o,DC=com} Path : LDAP://CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services, CN=Services, CN=Configuration, DC=contoso,DC=COM [Administrator]
Уже отсюда невооружённым глазом видны имена CA. Собственно, можно показать только имя самого CA и компьютера, на котором работает этот CA:
[Administrator] $ca.Children | ft Name, DNSHostName Name DNSHostName ---- ----------- {contoso-DC2-CA} {dc2.contoso.com} {Contoso CA} {DC1.contoso.com} [Administrator]
Здесь есть один важный нюанс. Если получить этот LDAP объект в PowerShell 1.0, то он будет содержать только Distinguished Name, а свойство Children будет отсутствовать в нём. Для этого нужно воспользоваться свойством PSBase, в котором уже будет Children. Командой Select можете выводить на экран и другие свойства, какие вы захотите:
PS C:\> $ca.children MemberType : Method OverloadDefinitions : TypeNameOfValue : System.Management.Automation.PSMethod Value : Name : children IsInstance : True PS C:\> $ca.psbase.children distinguishedName ----------------- {CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com} {CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com} PS C:\> $ca.psbase.children | select Name, DNSHostname Name DNSHostname ---- ----------- {contoso-DC2-CA} {dc2.contoso.com} {Contoso CA} {DC1.contoso.com} PS C:\>
Поэтому для обратной совместимости между версиями лучше использовать PSBase. В этом объекте будут содержаться не только CA вашего домена, а во всех доменах вашего леса, поскольку эта часть AD реплицируется как Forest naming context, т.е. между всеми контроллерами в лесу. Жизнь была бы неинтересной, если в каждом новом домене приходилось бы переписывать хвост (которая определяет домен, в котором следует искать) каждый раз. Для универсальности можно пойти на военную хитрость — раздобыть FQDN текущего домена, разобрать его и воткнуть в LDAP запрос. Получить имя текущего домена можно очень просто, с использованием статического метода GetCurrentDomain() класса System.DirectoryServices.ActiveDirectory.Domain. На самом деле у этого класса есть ещё куча других полезных методов, поэтому не лишним будет заглянуть по ссылке.
PS C:\> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() Forest : contoso.com DomainControllers : {DC1.contoso.com} Children : {} DomainMode : Windows2003Domain Parent : PdcRoleOwner : DC1.contoso.com RidRoleOwner : DC1.contoso.com InfrastructureRoleOwner : DC1.contoso.com Name : contoso.com PS C:\>
И свойство Name будет содержать имя нашего домена. Что дальше? А дальше, вполне очевидно, что нам надо заменить все точки на строку вида ", DC=". Вот так:
PS C:\> "contoso.com" -replace "\.", ", DC=" contoso, DC=com
А перед первым именем эту часть можно написать ручками. В итоге универсальная часть кода получится вот такая:
$domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name $domain = "DC=" + $domain -replace '\.', ", DC=" $CA = [ADSI]"LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, $domain"
Вот теперь у нас есть всё необходимое, чтобы написать простеньку функцию:
function Get-CertificationAuthority ([string]$CAName) { $domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name $domain = "DC=" + $domain -replace '\.', ", DC=" $CA = [ADSI]"LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, $domain" $CAs = $CA.psBase.Children | %{ $current = "" | Select CAName, Computer $current.CAName = $_ | %{$_.Name} $current.Computer = $_ | %{$_.DNSHostName} $current } if ($CAName) {$CAs = @($CAs | ?{$_.CAName -eq $CAName})} if ($CAs.Count -eq 0) {throw "Sorry, here is no CA that match your search"} $CAs }
Если выполнить эту функцию без аргументов, то она вернёт все CA в лесу. Но можно указать и какой-то один для каких-то других целей.
По мотивам предыдущего поста и срача в ньюсгруппе microsoft.public.windows.powershell перепубликовываю скрипт Роберта Робело для определения кодировки, в которой сохранён файл.
filter Get-TextEncoding { #requires -Version 2.0 begin { [string]$BOM_Unicode = [Text.Encoding]::Unicode.GetPreamble() [string]$BOM_UTF7 = [Text.Encoding]::UTF7.GetPreamble() [string]$BOM_UTF8 = [Text.Encoding]::UTF8.GetPreamble() [string]$BOM_BigEndian = [Text.Encoding]::BigEndianUnicode.GetPreamble() [string]$BOM_UTF32 = [Text.Encoding]::UTF32.GetPreamble() } process { if ($_ -is 'IO.FileInfo') { $bytes = Get-Content -Literal $_.pspath -Encoding Byte -Total 4 -ErrorAction SilentlyContinue $value = if ($bytes) { if ($bytes[0..1] -as 'String' -eq $BOM_Unicode) {'Unicode'} elseif ($bytes[0..2] -as 'String' -eq $BOM_UTF7) {'UTF7'} elseif ($bytes[0..2] -as 'String' -eq $BOM_UTF8) {'UTF8'} elseif ($bytes[0..1] -as 'String' -eq $BOM_BigEndian) {'BigEndian'} elseif ($bytes[0..3] -as 'String' -eq $BOM_UTF32) {'UTF32'} # undetermined, no BOM else {'Unknown'} # undetermined, zero bytes } else {'Unknown'} $_ | Add-Member NoteProperty Encoding $value -PassThru # not an IO.FileInfo } else {$_} } }
ну и использование достаточно простое:
dir *.ps1 | Get-TextEncoding | Format-Table Name, Encoding
Уже тут видно мелкий косячок подсветки в PowerGUI. Name должно быть такого же цвета, что и Encoding. А выглядеть это будет примерно так:
[↓] [vPodans] dir desktop\*.ps1 | Get-TextEncoding | ft name, encoding Name Encoding ---- -------- Untitled1.ps1 BigEndian untitled2.ps1 UTF8 [↓] [vPodans]
Не забудьте, что это будет работать только в V2. Для PowerShell 1.0 придётся чуточку подпилить его.
Когда пользователь начинает работать с PowerShell, то со временем перед ним возникает вопрос — какой редактор (вернее сказать, среду разработки) выбрать? Решений уже достаточно много, чтобы было из чего выбирать:
в большинстве случаев выбор делают между первыми двумя продуктами. Иногда споры об этом переходят в разряд религиозных войн. Истинные фанаты PowerShell выбирают ISE. В принципе, как просто редактор он вполне неплох, т.к. уже есть в коробке (начиная с первых CTP версий PowerShell V2) и для работы с ним никаких телодвижений делать не надо. Однако с ним есть ряд трудностей:
В ISE отсутствует IntelliSense (автозавершение команд и свойств/методов объекта). А это весьма необходимая функция в среде разработки. Мне кажется, что это поняли уже все, кроме разработчиков PowerShell ISE. Вот как это может выглядеть:
При наведении курсора на команду, не отображаются подсказки (Tooltips). В PowerGUI это выглядит действительно классно, точь-в-точь как в Visual Studio:
Причём, на этой картинке можно нажимать на стрелочки вверх/вниз для просмотра типов данных, которые принимаются в качестве аргумента. При наведении на переменную PowerGUI показывает даже тип и содержимое переменной (в разумных пределах).
В ISE включена поддержка одноврменного редактирования нескольких скриптов (за счёт табов). Однако, все табы выполняются в одном runspace, что часто приводит к негативным последствиям, когда в двух разных табах используются одинаковые имена переменных. В связи с этим, данные из определённой переменной одного таба будут мигировать во второй таб, если эта переменная ещё не определена. Это может привести к неожиданным результатам работы скрипта.
ISE по умолчанию сохраняет файлы в Big Endian кодировке. Вроде бы ничего криминального, но... Set-Authenticodesignature не умеет подписывать скрипты в Big Endian кодировке! Поэтому вы не сможете подписать штатными средствами ни один скрипт, который был сохранён в ISE! Для этого нужно прибегать к грязным хакам. Т.е. использовать такую строку, которая переопределит кодировку, в которой скрипт будет сохранён:
$psISE.CurrentFile.Save([Text.Encoding]::UTF8)
Вы можете в нём исполнять свой сценарий до тех пор, пока не сохраните его в файл. А вот когда вы редактируете уже сохранённый скрипт, то получаете бонус в виде того, что скрипт не будет исполняться внутри ISE, если у вас политика исполнения скриптов выставлена в AllSigned. ISE об этом честно предупреждает:
Т.е. он сохраняет файл и пытается его запустить. В PowerGUI сделано куда более гуманно. Из основного редактора код условно копируется и вставляется в консоль PowerShell. Т.е. вы можете спокойно редактировать и отлаживать свой скрипт и только когда он будет готов к работе — подписывать скрипт. В случае с ISE вам придётся либо после каждого изменения сохранять и переподписывать скрипт (а это дико неудобно), либо выделять весь код и выбирать Run Selection. А это тоже не очень удобно. Плюс, сохранение скрипта перед исполнением ведёт к другой проблеме. Вы не сможете отменить изменения на более раннее состояние.
В ISE вы не можете использовать свой профиль (который в консоли содержится в переменной $Profile), а только поддерживать дополнительный профиль, который находится в той же папке, что и основной, но под именем Microsoft.PowerShellISE_profile.ps1
ISE не поддерживает проверку файла на изменения, хотя это должно быть удобно. Я часто редактирую свои файлы дома на нотебуке и на работе. Папка со скриптами синхронизируется между домом и работой через Live Sync. Я достаточно редко закрываю редактор, поэтому вечером сохраняю файл (который уже открыт в редакторе на работе) и всё. Утром, придя на работу я могу без переоткрытия файла могу продолжать его редактировать. PowerGUI просто сообщит, что файл был изменён и сам предложит загрузить последнюю сохранённую версию. С ISE придётся вручную переоткрывать файл.
Я не могу вспомнить программ, которые бы имели меню Help, но внутри не имели подменю About. но это просто мелочи уже, которые не влияют на удобство разработки скриптов.
Updated 04.10.2009
Если подвести это всё в табличку, то получится примерно так:
PowerShell ISE | PowerGUI | PowerShell Plus | |
Built-In | :yes: | :no: | :no: |
Is free | :yes: | :yes: | :no: |
Fast start | :no: | :no: | :no: |
Powershell Support | 100% | <100% | <100% |
External PowerShell window | :yes: | :yes: | :yes: |
Remote PowerShell tab | :yes: | :no: | :no: |
IntelliSense | :no: | :yes: | :yes: |
Multiple Runspaces | :yes: | :yes: | :no: |
ToolTips | :no: | :yes: | :yes: |
Syntax highlighting | :yes: | :yes: | :yes: |
Error syntax highlighting | :no: | :yes: | :yes: |
Error autocorrection | :no: | :no: | :yes: |
Changed lines highlighting | :no: | :yes: | :yes: |
Outline support | :no: | :yes: | :yes: |
Support for signing | :no: | :yes: | :yes: |
Can sign within IDE | :no: | :no: | :yes: |
Run signed scripts in external window | :yes: | :no: | :yes: |
Readable command help | :yes: | :yes: | :yes: |
Configurable editor panes | :yes: | :yes: | :yes: |
Variable pane | :no: | :yes: | :yes: |
PS $Profile support | :no: | :yes: | :yes: |
BreakPoints | :yes: | :yes: | :yes: |
Code templates | :no: | :yes: | :yes: |
Print from editor | :no: | :yes: | :yes: |
Script autosave | :no: | :yes: | :yes: |
Примечание: последнее изменение таблицы 16.03.2010
Вобщем, я обозначил те вещи, которые я хотел бы видеть в хорошем редакторе. И значительное большинство моих хотелок уже есть в PowerGUI. О достоинствах PowerGUI можно говорить сколько угодно, но не буду смущать Диму Сотникова, поэтому скажу, что их продукт очень крутой. Но, в то же время, есть к чему стремиться. :-)
Однако, хочу ещё раз напомнить, что PowerGUI никогда не закроет первую строчку в таблице, что для религиозных фанатиков будет самым главным преимуществом и, который, затмит остальные недостатки ISE. Но мой выбор в этом вопросе достаточно очевиден.
После небольшого перерыва продолжаю допиливать свой вариант FCIV на PowerShell. И радостно могу сообщить, что уже есть версия 1.0, т.е. полностью отвечающая нашим требованиям. Что изменилось в новой версии?
А теперь и on-line справка по всем параметрам по просьбе трудящихся.
Несколько примеров использования:
Start-PsFCIV C:\Files db.xml -SHA1 -Recurse -Show Bad, Missed
будет проверена папка C:\Files и все вложенные папки. Файл db.xml должен быть размещён непосредственно в этой папке. Если файл не существует, то будет создан с нуля. После проверки будет показано графическое окно с именами файлов, которые попали в категорию Bad и Missed. Для каждой категории будет отдельное графическое окно.
Start-PsFCIV C:\Files db.xml -SHA1 -MD5 -Include data.dat
будет проверен только файл data.dat в папке C:\Files с использованием SHA1 алгоритмом хешиования. Если для файла в БД записан только MD5 хеш, то проверка будет произведена с использованием MD5. Если файл БД (db.xml) не существует, то создастся новый файл БД со сведениями о файле data.dat. Файл будет подсчитан с использованием как SHA1, так и MD5.
Start-PsFCIV C:\Files db.xml -SHA1 -MD5 -Rebuild
будет произведено освежение файла БД для папки C:\Files. Все записи, для которых соответствующего файла не обнаружено, будут удалены. Если в папке есть файлы, для которых нет соответствующей записи, то они будут обсчитаны с использованием алгоритмов SHA1 и MD5 и будут добвлены в XML файл. Файл db.xml должен существовать, иначе скрипт вернёт фатальную ошибку.
Start-PsFCIV C:\Files db.xml -SHA1 -Quiet
Папка C:\Files будет проверена в несопровождаемом режиме с использованием алгоритма SHA1. По умолчанию никакой информации на экране не будет. После окончания работы, в зависимости от результатов проверки, скрипт сгенерирует соответствующий код возврата (0-5).
И, собственно, сам скрипт:
И как обычно, любые замечания, комментарии постить в каменты.