Page 1 of 3 in the PowerShellWMI category Next Page

Мне вчера на почту пришёл комментарий на пост: Смена владельца папки или файла в PowerShell (часть 2), в котором сообщалось об ошибке, которую генерирует скрипт, если в пути есть служебные мета-символы, как апостроф (одиночкая кавычка). А дело было в том, что этот мета-символ нужно дополнительно эскейпить (помимо обратных слешей в пути). То же касается и квадратных скобок. Одиночные кавычки эскейпятся очень просто – одним обратным слешем:

[↓] [vPodans] $path = "C:\Users\vPodans\text'text.txt" [↓] [vPodans] $path = $path -replace "\\|'", '\$0' [↓] [vPodans] $path C:\\Users\\vPodans\\text\'text.txt [↓] [vPodans] gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'" __GENUS : 2 __CLASS : Win32_LogicalFileSecuritySetting __SUPERCLASS : Win32_SecuritySetting __DYNASTY : CIM_Setting __RELPATH : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text'text.txt" <...>

Но с квадратными скобками такой фокус не прошёл:

[↓] [vPodans] $path = "C:\Users\vPodans\text[text.txt" [↓] [vPodans] $path = $path -replace "\\|\[", '\$0' [↓] [vPodans] $path C:\\Users\\vPodans\\text\[text.txt [↓] [vPodans] gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'" Get-WmiObject : Invalid query At line:1 char:5 + gwmi <<<< Win32_LogicalFileSecuritySetting -filter "path='$path'" + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand [↓] [vPodans]

попытка заэскейпить квадратные скобки при помощи бэктика (`) успехом не увенчалась:

[↓] [vPodans] $path = "C:\Users\vPodans\text[text.txt" [↓] [vPodans] $path = $path -replace "\\", '\$0' [↓] [vPodans] $path = $path -replace "\[", '`$0' [↓] [vPodans] gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'" [↓] [vPodans]

он вообще файл не нашёл так. На удачу решил опробовать хитрый вариант – не эскейпить символ, а вписать его char номер из таблицы ASCII. И вот что у меня вышло:

[↓] [vPodans] $path = "C:\Users\vPodans\text[text.txt" [↓] [vPodans] $path = $path -replace "\\", '\$0' [↓] [vPodans] [int][char]"[" 91 [↓] [vPodans] $path = $path -replace "\[", "$([char]91)" [↓] [vPodans] $path C:\\Users\\vPodans\\text[text.txt [↓] [vPodans] gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'" __GENUS : 2 __CLASS : Win32_LogicalFileSecuritySetting __SUPERCLASS : Win32_SecuritySetting __DYNASTY : CIM_Setting __RELPATH : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text[text.txt" <...>

И этот финт сработал! Тот же самый манёвр делается и для второй квадратной скобки:

[↓] [vPodans] $path = "C:\Users\vPodans\text[text].txt" [↓] [vPodans] $path = $path -replace "\\", '\$0' [↓] [vPodans] $path = $path -replace "\[", "$([char]91)" [↓] [vPodans] [int][char]"]" 93 [↓] [vPodans] $path = $path -replace "\]", "$([char]93)" [↓] [vPodans] $path C:\\Users\\vPodans\\text[text].txt [↓] [vPodans] gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'" __GENUS : 2 __CLASS : Win32_LogicalFileSecuritySetting __SUPERCLASS : Win32_SecuritySetting __DYNASTY : CIM_Setting __RELPATH : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text[text].txt" <...>

Но в именах файлов и папок может содержаться один коварный символ – backtick (`). Его заэскейпить не представляется возможным, поэтому единственный выход с ним – прописывать путь в одинарных кавычках, чтобы этот мета-символ использовался в качестве литерала. В связи с чем я немного подрихтовал пост, ссылка на который приведена в начале этого поста.

Friday, July 24, 2009 11:32:55 PM (FLE Daylight Time, UTC+03:00)   Comments [0]    

 

В своём предыдущем блоге я писал заметку про то, как можно случайно удалить классы WMI – PowerShell - убийца WMI классов? И недавно узнал, как можно восстановить эту функциональность обратно. Сами Win32 классы находятся в библиотеке CIMWIN32.MOF, которая и повреждается при удалении классов. Чтобы вернуть эти классы – достаточно перекомпилировать эту библиотеку:

C:\Windows\System32\wbem\MOFComp CIMWIN32.MOF

[↑] [system32] gwmi win32_share Name Path Description ---- ---- ----------- ADMIN$ C:\Windows Remote Admin C$ C:\ Default share D$ D:\ Default share IPC$ Remote IPC P$ P:\ Default share print$ C:\Windows\system32\spool\drivers Printer Drivers Work D:\Users\vpodans\Work Z$ Z:\ Default share _Shared Documents D:\Users\_Shared Documents [↑] [system32] [wmiclass]'win32_share' NameSpace: ROOT\cimv2 Name Methods Properties ---- ------- ---------- Win32_Share {Create, SetShare... {AccessMask, AllowMaximum, Caption, Description...} [↑] [system32] ([wmiclass]'win32_share').delete() [↑] [system32] gwmi win32_share Get-WmiObject : Invalid class At line:1 char:5 + gwmi <<<< win32_share + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand [↑] [system32] cd wbem [↑] [wbem] MOFComp CIMWIN32.MOF Microsoft (R) MOF Compiler Version 6.0.6000.16386 Copyright (c) Microsoft Corp. 1997-2006. All rights reserved. Parsing MOF file: CIMWIN32.MOF MOF file has been successfully parsed Storing data in the repository... Done! [↑] [wbem] gwmi win32_share Name Path Description ---- ---- ----------- ADMIN$ C:\Windows Remote Admin C$ C:\ Default share D$ D:\ Default share IPC$ Remote IPC P$ P:\ Default share print$ C:\Windows\system32\spool\drivers Printer Drivers Work D:\Users\vpodans\Work Z$ Z:\ Default share _Shared Documents D:\Users\_Shared Documents [↑] [wbem]

Вот так я сначала показал, как можно убить класс WMI и восстановить его обратно очень простым способом.

Saturday, July 18, 2009 4:45:06 PM (FLE Daylight Time, UTC+03:00)   Comments [4]    

 

По просьбе читателей, а так же с учётом востребованности (судя по сообщениям форумов и ньюсгрупп) я нашёл время переписать скрипт ShareUtils.ps1 с поддержкой работы с удалёнными машинами и попутно пофиксив недочёты, которые были найдены за время эксплуатации предыдущей версии скрипта. Предыдущая версия опубликована здесь: http://vpodans.spaces.live.com/blog/cns!BB1419A2CFC1E008!188.entry

Технический функционал изменился только возможностью работы с удалёнными компьютерами, но синтаксис был изменён (а так же удалены лишние функции) по аналогии с PrinterUtils и имеет примерно следующий вид:

  1. New-Share –Computer <Computer> –Name <Name> –Path <Path> –Description <Description>
    где Computer – имя или IP адрес компьютера, на котором необходимо расшарить папку. (не обязательный параметр). Если не указан, используется текущий компьютер.
    Name - сетевое имя для папки;
    Path - путь к физической папке;
    Description описание к сетевой папке. При наличии пробелов -  заключить в кавычки (не обязательный параметр);
  2. Remove-Share –Computer <Computer> –Name <Name> – отменяет расшаривание на папке. Сама папка не удаляется.
    где Computer – имя или IP адрес компьютера, на котором нужно отменить расшаривание папки. (не обязательный параметр). Если не указан, используется текущий компьютер.
    Name - сетевое имя папки;
  3. Get-Share –Computer <Computer> –Name <Name> – получает основные сведения и списки DACL Share Permissions с указанных или всех сетевых папок.
    где Computer – имя или IP адрес компьютера, с которого нужно получить сведения о сетевых папках. (не обязательный параметр). Если не указан, используется текущий компьютер.
    Name - имя сетевой папки (не обязательный параметр). Если не указан, то выбираются все сетевые папки с типом Disk Drive (в которые системные шары не входят).
  4. Set-SharePermission –User <User> –AceType <AceType> –AccessMask <AccessMask> – устанавливает единственный Share Permission ACE для указанного в аргументах пользователя.
    User - имя пользователя/группы, которой предоставляется доступ;
    AceType - тип доступа. Этот параметр должен иметь одно из значений Allow/Deny;
    AccessMask - маска доступа. Этот параметр должен иметь одно из значений FullControl/Change/Read;

    Функция не может быть вначале строки, а только после конвейера Get-Share или другого источника с подходящими данными (например, если данные были сохранены в CSV/XML файле, то их можно использовать в качестве источника: Import-Csv path.csv | Set-SharePermission Everyone Allow Change). При этом все текущие права на сетевую папку будут удалены и записан только указанный в аргументах пользователь/группа.
  5. Add-SharePermission –User <User> –AceType <AceType> –AccessMask <AccessMask> – добавляет указанного в аргументах пользователя к Share Permissions выбранной сетевой папки (или папок)
    User - имя пользователя/группы, которой предоставляется доступ;
    AceType - тип доступа. Этот параметр должен иметь одно из значений Allow/Deny;
    AccessMask - маска доступа. Этот параметр должен иметь одно из значений FullControl/Change/Read;

    Функция не может быть вначале строки, а только после конвейера Get-Share или другого источника с подходящими данными (например, если данные были сохранены в CSV/XML файле, то их можно использовать в качестве источника: Import-Csv path.csv | Add-SharePermission Everyone Allow Change).
  6. Remove-SharePermission –User <User> – удаляет указанного пользователя из DACL выбранной сетевой папки (папок). Не может быть вначале строки, а только на выходе конвейера, откуда поступают объекты сетевых папок. Например, Get-Share | Remove-SharePermission Everyone – удалит группу Everyone из всех SharePermissions всех расшаренных папок на локальном компьютере. Разрешения NTFS при этом не изменяются.
    где User - имя пользователя/группы, которого следует удалить из ACL сетевой папки.

Примеры использования практически идентичные, как и в PrinterUtils: http://www.sysadmins.lv/PermaLink,guid,22c0550d-0c46-44ca-97ce-2b0bccbb51de.aspx

И, собственно, сам код:

########################################################
# ShareUtils.ps1
# Version 0.9
#
# Functions for advanced share management
#
# Note:
# Previous version is published at my former blog:
# http://vpodans.spaces.live.com/blog/cns!BB1419A2CFC1E008!188.entry
#
# Vadims Podans (c) 2009
# http://www.sysadmins.lv/
######################################################## 

# внутренняя функция, которая преобразовывает числовой код возврата операции записи DACL
# в текстовое значение.
function _ShareUtils_Get-Code ($write) {
switch ($write.ReturnValue) {
   "0" {"Success"}
   "2" {"Access Denied"}
   "8" {"Unknown Failure"}
   "9" {"Invalid Name"}
   "21" {"Invalid Parameter"}
   "22" {"Duplicate Share"}
   "23" {"Redirected Path"}
   "24" {"Unknown Device or Directory"}
   "25" {"Net Name Not Found"}
   default {"Unknown error $write.ReturnValue"}
   }
}

# функция для извлечения сведений и DACL с существующих сетевых папок.
# обязательна для использования функций Add-SharePermission и Set-SharePermission
# если компьютер не указан, то используется текущий. Если имя сетевой паки не указано,
# то возвращается список сведений и DACL всех сетевых папок на локальном или удалённом компьютере
function Get-Share ($computer = ".", $name) {
    if ($name) {
        $shares = gwmi Win32_Share -ComputerName $computer -Filter "name = '$name'"
    } else {
        $shares = gwmi Win32_Share -ComputerName $computer -Filter "type = 0"
    }
    $ShareInfo = @()
    foreach ($share in $shares) {
        $ShareSec = gwmi Win32_LogicalShareSecuritySetting -ComputerName $computer -filter "name='$($share.name)'" 
        if ($shareSec) {
            $SD = $sharesec.GetSecurityDescriptor()
            $ShareInfo += $SD.Descriptor.DACL | % {
                $_ | select @{e={$share.ClassPath.Server};n='Computer'},
                @{e={$share.name};n='Name'},
                @{e={$share.Path};n='Path'},
                @{e={$share.Description};n='Description'},
                AccessMask,
                AceFlags,
                AceType,
                @{e={$_.trustee.Name};n='User'},
                @{e={$_.trustee.Domain};n='Domain'},
                @{e={$_.trustee.SIDString};n='SID'}
            }
        } else {
            Write-Warning "Specified share not exist or you may not have sufficient rights to access them!"
        }
$ShareInfo
    }
}

# функция записи обновлённых сведений в сетевые папки. Не может быть первой в строке, а только после
# конвейера, откуда поступают данные для записи. Если папка не расшарена, то скрипт её расшарит
# автоматически и запишет необходимые сведения о сетевой папке.
function Set-Share {
    $ShareInfo = @($input)
    $ShareInfo | select -unique Computer, Name, Path, Description | % {
        $Computer = $_.Computer
        $name = $_.name
        $SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
        $ace = ([WMIClass] "Win32_Ace").CreateInstance()
        $Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
        $sd.DACL = @()
        $ShareInfo | ? {$_.Computer -eq $Computer -and $_.name -eq $name} | % {
            $SID = new-object security.principal.securityidentifier($_.SID)
            [byte[]] $SIDArray = ,0 * $SID.BinaryLength
            $SID.GetBinaryForm($SIDArray,0)
            $Trustee.Name = $_.user
            $Trustee.SID = $SIDArray
            $ace.AccessMask = $_.AccessMask
            $ace.AceType = $_.AceType
            $ace.AceFlags = $_.AceFlags
            $ace.trustee = $Trustee
            $SD.DACL += $ace.psObject.baseobject
        }
# проверяется наличие расшаренной папки. Если папка есть, то в неё записывается только SecurityDescriptor
# в противном случае она расшаривается и в неё производится полная запись всех данных
        $share = gwmi Win32_Share -ComputerName $computer -Filter "name = '$name'"
        if ($share) {
            $inParams = $share.psbase.GetMethodParameters("SetShareInfo")
            $inParams.Access = $SD
            $write = $share.psbase.invokemethod("SetShareInfo", $inParams, $null)
            Write-Host "Setting DACL on current share: $name on server $computer" -ForegroundColor green
            _ShareUtils_Get-Code $Write
        } else {
            $shareobject = [wmiClass]"\\$computer\root\cimv2:win32_Share"
            $inParams = $shareobject.psbase.GetMethodParameters("Create")
            $inParams.name = $_.name
            $inParams.path = $_.path
            $inParams.Description = $_.Description
            $inParams.Type = 0
            $inParams.Access = $SD
            $write = $shareobject.psbase.invokemethod("Create", $inParams, $null)
            Write-Host "Processing current share: $name on server $computer" -ForegroundColor green
            _ShareUtils_Get-Code $Write
        }
    }
}

function _Create-SDObject ($user, $AceType, $AccessMask) {
    # преобразование текстового вида прав в числовые значения
    $masks = @{FullControl = 2032127; Change = 1245631; Read = 1179817}
    $types = @{Allow = 0; Deny = 1}
    # создание необходимых свойств для объекта. Для поддержки удалённого управления
    # было добавлено свойство Computer, которое будет принимать от Get-Share аналогичное
    # значение. Тем самым обеспечивается сквозная трансляция имени компьютера, где
    # находится сетевая папка, по конвейеру для последующей записи
    $AddInfo = New-Object System.Management.Automation.PSObject
    $AddInfo | Add-Member NoteProperty Computer  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty Name  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty Path  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty Description  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty AccessMask  ([uint32]$null)
    $AddInfo | Add-Member NoteProperty AceFlags  ([uint32]$null)
    $AddInfo | Add-Member NoteProperty AceType  ([uint32]$null)
    $AddInfo | Add-Member NoteProperty User  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty Domain  ([PSObject]$null)
    $AddInfo | Add-Member NoteProperty SID  ([PSObject]$null)
    # заполнение объекта данными, которые были указаны в качестве аргументов вызова функции и возврат
    # объекта в вызывающую функцию
    $AddInfo.Name = $name
    $AddInfo.User = $user
    $AddInfo.SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier])
    $AddInfo.AccessMask = $masks.$AccessMask
    $AddInfo.AceType = $types.$AceType
    $AddInfo
}

function Set-SharePermission ($user, $AceType, $AccessMask) {
    # принимаются данные с конвейера 
    $ShareInfo = @($input)
    $AddInfo = _Create-SDObject $user $AceType $AccessMask
    # в этом цикле перебираются по именам все имена расшаренных папок и для каждой из них
    # записывается указанный в аргументах пользователь с удалением текущих ACE из ACL шары
    # это видно по тому, что никакая часть $ShareInfo не передаётся по конвейеру на запись
    foreach ($share in ($ShareInfo | select -Unique Computer, Name)) {
        $AddInfo.Computer = $share.Computer
        $AddInfo.Name = $share.name
        $AddInfo.Description = $Share.Description
        $AddInfo | Set-Share
    }
}

# просто добавляет нового участника безопасности к текущему DACL расшаренной папки.
# NTFS Acl не изменяется.
function Add-SharePermission ($user, $AceType, $AccessMask) {
    $ShareInfo = @($input); $ShareInfoNew = @()
    $AddInfo = _Create-SDObject $user $AceType $AccessMask
    foreach ($Share in ($ShareInfo | select -Unique Computer, Name)) {
        $AddInfo.Name = $Share.name
        $AddInfo.Computer = $Share.Computer
        $AddInfo.Description = $Share.Description
        # вот этой строкой мы из списка всех сетевых папок итеративно перебираем каждую шару
        $ShareInfoNew = @($ShareInfo | ?{$_.name -eq $Share.name})
        # в хвост списка ACL каждой сетевой шары добавляем новый ACE
        $ShareInfoNew += $AddInfo
        # и подаём на запись
        $ShareInfoNew | Set-Share
    }
}

# основная функция для удаления единичного ACE из ACL сетевой папки. Процесс сводится к извлечению
# текущего списка (или списков) ACL и фильтрации ACE в этом списке по методу Not Equal. Всё, что не подпадает под
# это действие записываются обратно в переменную, а всё, что подпало (указанный пользователь) обратно
# в переменную $ShareInfo не записывается.
function Remove-SharePermission ($user) {
    $shares = @($input)
    # просто берём списки ACL, которые пришли по конвейеру и выкидываем оттуда все ACE,
    # в которых фигурирует указанный в аргументах пользователь/группа и записывем ACE обратно в ACL
    $shares | ? {$_.user -ne $user} | Set-Share
}

# основная функция для создания новых сетевых папок на локальном компьютере. Здесь я использую упрощённый
# вариант создания сетевой папки, но учитывая один большой нюанс я добавил одно действие. Суть проблемы
# изложена тут: http://vpodans.spaces.live.com/blog/cns!BB1419A2CFC1E008!170.entry
# поэтому при создании новой сетевой папки я вручную создаю с нуля список ACL, который содержит # только группу Everyone и с правом Allow Read. function New-Share ($computer = $env:COMPUTERNAME, $name, $path, $Description) { $user = (new-object security.principal.securityidentifier "S-1-1-0").translate([security.principal.ntaccount]) $AddInfo = _Create-SDObject $user.Value Allow Read $AddInfo.Computer = $computer $AddInfo.Path = $path $AddInfo.Description = $Description $AddInfo | Set-Share } # отменяет расшаривание сетевой папки. Сама же физическая папка не изменяется. function Remove-Share ($computer = ".", $name) { $share = gwmi Win32_Share -ComputerName $computer -Filter "name = '$name'" if (!$share) { Write-Warning "Specified network share doesn't exist!" } else { $write = $share.delete() Write-Host "Deleting network share $name on computer $computer:" _ShareUtils_Get-Code $write } }
PowerShell |  ACL |  WMI
Wednesday, March 04, 2009 4:22:45 PM (FLE Standard Time, UTC+02:00)   Comments [0]    

 

Этот скрипт написал скорее для себя, но весьма полезный. В Windows XP/Windows Server 2003 аптайм можно было легко посмотреть в свойствах сетевого подключения, которое как правило работает постоянно. Но в Windows Vista/Windows Server 2008 до него добираться далеко. Смотреть в Task Manager не удобно, поскольку он показывает аптайм в часах, а в уме высчитывать дни как-то неудобно. Вот и набросал функцию, которую положил себе в профиль:

function Get-SystemUptime ($computer = "$env:computername") {
    $lastboot = [System.Management.ManagementDateTimeconverter]::ToDateTime(
    "$((gwmi  Win32_OperatingSystem -computername $computer).LastBootUpTime)")
    $uptime = (Get-Date) - $lastboot
    Write-Host "System Uptime for $computer is: " $uptime.days "days" $uptime.hours `
    "hours" $uptime.minutes "minutes" $uptime.seconds "seconds"
}

Концепция очень простая – берётся дата и время последней загрузки системы и вычитается из текущей даты и времени. Здесь важно отметить, что WMI возвращает нам дату в своём формате, который нужно преобразовать в тип DateTime.

Sunday, February 15, 2009 8:07:38 PM (FLE Standard Time, UTC+02:00)   Comments [0]    

 

Windows Management Instrumentarion или просто WMI в PowerShell V2 так же претерпел изменения, а точнее дополнения по сравнению с версией 1.0. Я планирую более подробно описать новые и обновлённые параметры командлета Get-WMIObject:

1) -List - ключ. Позволяет получать список классов для системы или список свойств и методов для конкретного класса:

[vPodans] Get-WmiObject -List


   NameSpace: ROOT\cimv2

Name                                Methods              Properties
----                                -------              ----------
__NotifyStatus                      {}                   {StatusCode}
__ExtendedStatus                    {}                   {Description, Operation, ParameterInfo, ProviderName...}
Win32_PrivilegesStatus              {}                   {Description, Operation, ParameterInfo, PrivilegesNotHeld...}
Win32_JobObjectStatus               {}                   {AdditionalDescription, Description, Operation, ParameterIn...
__SecurityRelatedClass              {}                   {}
__Trustee                           {}                   {Domain, Name, SID, SidLength...}
Win32_Trustee                       {}                   {Domain, Name, SID, SidLength...}
__NTLMUser9X                        {}                   {Authority, Flags, Mask, Name...}
....

По умолчанию, без указания других параметров, параметр -List выводит список классов, которые расположены в контейнере по умолчанию Root\CimV2. Но можно указывать и другие контейнеры при помощи параметра -NameSpace. Например:

Get-WmiObject -Namespace root\default -List

Или для конкретного класса:

[vPodans] Get-WmiObject Win32_share -List | select * | fl


Name             : Win32_Share
__GENUS          : 1
__CLASS          : Win32_Share
__SUPERCLASS     : CIM_LogicalElement
__DYNASTY        : CIM_ManagedSystemElement
__RELPATH        : Win32_Share
__PROPERTY_COUNT : 10
__DERIVATION     : {CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER         : THOR
__NAMESPACE      : ROOT\cimv2
__PATH           : \\THOR\ROOT\cimv2:Win32_Share
Path             : \\THOR\ROOT\cimv2:Win32_Share
Derivation       : {CIM_LogicalElement, CIM_ManagedSystemElement}
Methods          : {Create, SetShareInfo, GetAccessMask, Delete}
Scope            : System.Management.ManagementScope
Options          : System.Management.ObjectGetOptions
ClassPath        : \\THOR\ROOT\cimv2:Win32_Share
Properties       : {AccessMask, AllowMaximum, Caption, Description...}
SystemProperties : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}
Qualifiers       : {CreateBy, DeleteBy, dynamic, Locale...}
Site             :
Container        :



[vPodans]

здесь мы видим доступные методы (Create, SetShareInfo и другие), а так же свойства объекта класса (AccessMask, AllowMaximum, Caption и другие). Можно и более подробно посмотреть методы или свойства объекта:

Get-WmiObject Win32_share -List | %{$_.methods} - получение подробных сведений о методах объекта класса
Get-WmiObject Win32_share -List | %{$_.properties} - получение подробных сведений о свойствах объекта класаа

Кстати говоря, в PowerShell 1.0 параметр -List не работал для конкретных классов, а только для перечисления самих классов. Т.е. приведённые выше 2 команды в 1.0 не работают. Теперь этот недостаток исправлен.

2) -AsJob - ключ. Позволяет выполнять команду в фоновом режиме. Это новая возможность в PowerShell V2, которая позволяет запускать некоторые команды в фоновом режиме не блокируя при этом саму консоль. Коллега, Вася Гусев, уже делал скринкаст по фоновым работам в PowerShell (и не только о них) на TechDays.ru (потребуется авторизация с помощью LiveID или OpenID). И я так же планирую обсудить в своём блоге этот вопрос в обозримом будущем.

3) -Authentication - параметр. Позволяет задавать уровень аутентификации к удалённой машине. Возможные уровни аутентификации могут быть:

  • -1 (Unchanged) - я не смог найти описание этому уровню, но он в Windows XP/Windows Server 2003 используется для локальных подключений на себя.
  • 0 (Default) - необходимый уровень будет согласовываться между сервером и клиентом в зависимости от настроек Windows Authentication.
  • 1 (None) - не использует аутентификацию. Все уровни безопасности будут проигнорированы. Не следует использовать этот уровень, поскольку с ним аутентифицироваться не удастся (разве что в случае разрешённых анонимных подключений на сервере).
  • 2 (Connect) - клиент аутентифицируется только при установке подключения. После установки подключения аутентификационные данные не проверяются.
  • 3 (Call) - пересылаемые учётные данные проверяются при каждом запросе клиента. Учётные данные криптографически подписываются, но не шифруются. Пересылаемые данные во время сессии не подписываются и не шифруются. Гарантируется, что во время пересылки аутентификационных данных они не были никоим образом изменены.
  • 4 (Packet) - похож на уровень Call с учётом того, что сервер проверяет что данные пришли от ожидаемого клиента. Так же учётные данные подписываются и не шифруются. Данные не подписываются и не шифруются (используется по умолчанию при сетевых подключениях).
  • 5 (PacketIntegrity) - подписываются как учётные данные, так и сами пересылаемые данные. Данный уровень гарантирует, что с момента отправки от клиента до получения данных сервером любые данные не были изменены. Но данные (в том числе учётные) по прежнему не шифруются.
  • 6 (PacketPrivacy) - все передаваемые данные между клиентом и сервером подписываются и шифруются.

В версии 1.0 можно было изменять уровни аутентификации, но там были свои сложности. Например, при первом подключении нельзя было указывать свой уровень аутентификации, а только при последующих обращениях к серверу. Например так:

$a = Get-WmiObject Win32_share -filter "Name = 'sharename'"
$a.PSBase.Scope.Options.Authentication = 6
или PacketPrivacy

4) -Authority - параметр. Позволяет клиенту выбирать, кто будет его аутентифицировать (например, LSA удалённой машины или сервер Active Directory) при указании параметра -Credentials.

5) -DirectRead - ключ. Если указывается, то производится прямой доступ к классу без привязки к нему более высших или производных классов. Реальной пользы я тут пока что не вижу.

6) -Impersonation - параметр. В этом параметре можно указывать уровень имперсонализации при удалённых подключениях. Может иметь следующие значения:

  • 0 (Default) - так же не смог найти описания для него. Во всяком случае в самом WMI такой уровень нигде не определён и скорее всего это какой-то производный уровень из нескольких внутри самого PowerShell.
  • 1 (Anonymous) - При указании этого уровня учётные данные клиента скрываются. По факту WMI в современных версиях ОС скорее всего не поддерживает этот уровень, а переводит его в уровень Identify и использует его для имперсонализации клиента. В Windows 2000 было так, во всяком случае. Да и особого смысла в нём нету, поскольку с таким уровнем ничего сделать не удастся в общем смысле.
  • 2 (Identify) - позволяет объектам запрашивать учётные данные вызывающего пользователя, но не использовать их. Следовательно удалённый объект не сможет установить вас в контексте безопасности (т.е. подтвердить, что вы именно тот за кого себя выдаёте). С таким уровнем обычно можно только прочитать ACL списки объектов (и то не всегда), но не более.
  • 3 (Impersonate) - позволяет объектам использовать учётные данные вызывающего пользователя. Это в свою очередь позволяет пользователю использовать свои учётные данные для произведения любых операций над объектами в пределах прав пользователя на этот объект (обычно эти права задаются ACL списками). Данный уровень используется в PowerShell по умолчанию. Поэтому для использования уровня Impersonate данный параметр указывать не обязательно.
  • 4 (Delegate) - это уровень транзитивной делегации учётных данных. Это позволяет удалённым объектам передавать ваши учётные данные другим объектам на других машинах. Иными словами, когда пользователь с машины A подключается к машине B, то в этом случае используется уровень Impersonate между A и B. Но если для завершения операции объекту с машины B нужно получить ещё объект с машины C, то Delegate позволит машине B аутентифицироваться на машине C с учётными данными, которые были получены от машины A. Если совсем грубо, то пользователь просто разрешает запрашиваемым объектам использовать его учётные записи для своих нужд. Безусловно, это большой риск, когда объект может распоряжаться полученными учётными данными как хочет, поэтому все пользователи и компьютеры, которые будут участвовать в транзакции (например, пользователь и компьютеры A, B и C) должны быть помечены как Trusted For Delegation в Active Directory.

В версии 1.0 так же можно было изменять уровень имперсонализации с теми же сложностями, которые были и у параметра Authentication. А именно - нельзя было изменять этот уровень при первом подключении к WMI. Делалось это так:

$a = Get-WmiObject Win32_share -filter "Name = 'sharename'"
$a.PSBase.Scope.Options.Impersonation = 4
или Delegate

7) -EnableAllPrivileges - ключ. Данный ключ включает все привилегии безопасности (семейство SeSecurity Privilege), которыми обладает пользователь. Я уже не раз отмечал, что при работе в системе из графической оболочки Explorer, LSA (Local Security Authority) прозрачно для пользователя включает привилегии при необходимости. Однако, в целях безопасности для скриптов LSA по умолчанию не включает их. Привилегии безопасности нужны для многих операций, как смена владельца объектов, редактирования списков ACL множества объектов, выполнение критических для системы операции как удаление журналов событий, восстановления системы из точек восстановления и т.д. И только WMI нам предлагает интерфейс для их использования. Причём теперь это делается простым указанием ключа при использовании командлета Get-WmiObject. В общем смысле в версии 1.0 нельзя было из скриптов включать привилегии, хотя по факту данный функционал был заложен и активно использовался:

$a = Get-WmiObject Win32_share -filter "Name = 'sharename'"
$a.PSBase.Scope.Options.EnablePrivileges = $true

В этом отношении PowerShell является менее безопасным, чем, к примеру, VBS, который позволяет включать только необходимые привилегии безопасности (например для смены владельца объекта только SeRestorePrivilege и SeTakeOwnershipPrivilege). Причём VBS может очень гибко работать с подключаемыми привилегиями, что делает код более безопасным. В PowerShell они включаются все сразу и отдельные привилегии включать нельзя.

Вот, в принципе и рассмотрели основые полезные и интересные нововведения в командлет Get-WmiObject для работы с WMI в PowerShell V2 CTP3. Я допускаю, что эти параметры к релизу вряд ли претерпят существенные изменения и будут справедливы и в финальной версии V2.

Sunday, January 04, 2009 8:37:15 PM (FLE Standard Time, UTC+02:00)   Comments [0]    

 

Page 1 of 3 in the PowerShellWMI category Next Page
 · 
All content © 2008 - 2010, Vadims Podāns
"Spaces" Theme provided by: Vadims Podāns
About


E-mail - Send mail to the author(s)
Live Messenger -
My former blog -
For english language visitors

Translate via Google Translator

Библиотека
Календарик
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Карта расположения посетителей
Favorites

Домашняя страничка Теры Патрик

Disclaimer
Вся информация на сайте предоставляется на условиях «как есть», без предоставления каких-либо гарантий и прав.

При использовании материалов c данного сайта ссылка на оригинальный источник обязательна.