Форум программистов, компьютерный форум, киберфорум
Наши страницы
PowerShell
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
#1

Обновление DACL раздела реестра (не изменяется значение поля)

06.03.2016, 00:01. Просмотров 818. Ответов 14
Метки нет (Все метки)

Здравствуйте!

Подскажите, пожалуйста, почему не изменяется значение поля AceType структуры Win32_ACE (DACL) и как это исправить?
Вот я его повторно "в лоб" меняю в строке 38, а в следующей получаю старое значение - 1.

P.S. Чтобы проверить работу скрипта (создав раздел с нужными правами), просто нажмите ПКМ по любому архиву .zip -> Открыть с помощью -> Поставьте галку "Открывать всегда этой программой" -> OK.

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$FILE_WRITE_DATA = 2
$ACE_ALLOW = 0
$ACE_DENY = 1
$HKCU = [Uint32]'0x80000001'
 
# Current user's SID
$CurSID = ([wmi] "Win32_userAccount.Domain='$env:UserDomain',Name='$env:UserName'").SID
 
# Administrator's group SID
$AdmSID = "S-1-5-32-544"
 
$UC = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice"
 
$oWMI = get-wmiobject -list "StdRegProv" -namespace 'root\default' -EnableAllPrivileges
 
$SD = $oWMI.GetSecurityDescriptor($HKCU, $UC).Descriptor
 
# $SD.ControlFlags should contains SE_DACL_PRESENT flag
 
for ($i = 0; $i -lt $SD.DACL.count; $i++)
{
  $SID = $SD.DACL[$i].Trustee.SIDString
  if (($SID -eq $CurSID) -or ($SID -eq $AdmSID))
  {
    if ($SD.DACL[$i].AccessMask -bAnd $FILE_WRITE_DATA)
    {
      if ($SD.DACL[$i].AceType -eq $ACE_DENY)
      {
        $SD.DACL[$i]
        $SD.DACL[$i].Trustee
        $SD.DACL[$i].AceType = $ACE_ALLOW
      }
    }
  }
}
 
# test
$SD.DACL[0].AceType = 0
$SD.DACL[0].AceType
$SD.DACL[0].Trustee.SIDString
$SD.DACL[0].Trustee.Name
 
$Result = $oWMI.SetSecurityDescriptor($HKCU, $UC, $SD)
$Result
 
$host.ui.RawUI.ReadKey(6)|out-null
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.03.2016, 00:01
Ответы с готовыми решениями:

Нет требуемого раздела реестра
Требуется зайти в раздел реестра HKEY_LOCAL_MACHINEHKEY_LOCAL_MACHINESOFTWARE...

Экспорт раздела реестра в текстовом формате в файл
Приветствую, бразеры! Кто сталкивался с необходимостью экспортировать раздел...

Изменяется, но не отображается значение текстового поля компонента Forms
Доброго времени суток, уважаемые гуру! Проблема в том, что при успешном...

Не изменяется значение поля при команде UPDATE T-SQL в C#
Здравствуйте! Вот в чём суть: по нажатию кнопки необходимо изменить в таблице...

Как прописать обновление этого поля – т.е. “oninput” по условию, что меняется значение поля с датой?
Есть поле для выбора дат публикаций объявления в форме… <input type="text"...

14
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
06.03.2016, 00:23 #2
Цитата Сообщение от Dragokas Посмотреть сообщение
пожалуйста, почему не изменяется значение поля AceType структуры Win32_ACE (DACL) и как это исправить?
Вот здесь описана похожая проблема и в комментарии, Alexey Tregubov предлагает решить её так:

PowerShell
1
2
3
4
5
6
7
8
9
10
$SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
$ace = ([WMIClass] "Win32_Ace").CreateInstance()
...
$ace.AccessMask = 983052
$ace.AceType = 0
$ace.AceFlags = 0
$ace.Trustee = $Trustee
 
$SD.DACL += $ace # добавляем, их у нас может быть много 
$SD.ControlFlags="0x4" # set control flag
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
06.03.2016, 00:57  [ТС] #3
Спасибо, KDE777. Я читал ее.
Конечно, можно создать новый ACE, или скопировать текущий, но было интересно именно почему значение не изменяется.

Хотя и с примером от Alexey Tregubov тоже не все гладко.
Я с PS впервые, так что не совсем понимаю как правильно сделать инкремент для массива структур:
строка $SD.DACL += $ace выдает:
Исключение при задании "DACL" : "Не удалось привести тип объекта "System.Management.Automation.PSObject" к типу "System.Management.ManagementBaseObject"."
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
06.03.2016, 02:07 #4
Цитата Сообщение от Dragokas Посмотреть сообщение
Я с PS впервые, так что не совсем понимаю как правильно сделать инкремент для массива структур:
строка $SD.DACL += $ace выдает:
А вы $ace сделали, как там показано? У меня - $SD.DACL += $ace - работает без ошибок...

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
$user = "everyone"
 
$ace = ([WMIClass] "Win32_Ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
 
$SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier])
[byte[]] $SIDArray = ,0 * $SID.BinaryLength
$SID.GetBinaryForm($SIDArray,0)
 
$ace.AccessMask = 983052
$ace.AceType = 0
$ace.AceFlags = 0
$ace.Trustee = $Trustee
Добавлено через 44 минуты
Dragokas, Вот ещё пример, как к DACL добавляют новую ACE-запись - http://stackoverflow.com/questions/2...rom-powershell
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
06.03.2016, 02:38  [ТС] #5
KDE777, с кодом из поста № 1, как уже писал выше, точно не работает.
+ не знаю, какую роль играет переменная SID у Вас в коде выше, но у меня исключение уже на 6-й строке:

Код
Исключение при вызове "Translate" с "1" аргументами: "Некоторые или ссылки на свойства нельзя преобразовать."
H:\_Powershell\test.ps1:6 знак:65
+ $SID = (new-object security.principal.ntaccount $user).translate <<<< ([security.principal.securityidentifier])
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
Да и вообще какая разница, что там за значения в полях.
+= это как я понимаю просто операция добавления к массиву очередного элемента (структуры). Просто судя из ошибки, тип данных не совпал.
___________________

Здесь вот еще какая странность. Почему на PowerShell GetSecurityDescriptor принимает 2 аргумента:

Код
PS C:\Users\Alex> $oWMI.GetSecurityDescriptor

MemberType          : Method
OverloadDefinitions : {System.Management.ManagementBaseObject GetSecurityDescriptor(System.UInt32 hDefKey, System.Strin
                      g sSubKeyName)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.Management.ManagementBaseObject GetSecurityDescriptor(System.UInt32 hDefKey, System.String
                       sSubKeyName)
Name                : GetSecurityDescriptor
IsInstance          : True
если на MSDN явно указано, что у класса StdRegProv для этого метода аргументов - 3.

Вообщем попробовал тоже самое переписать на VBS.
Там все нормально, значение поля изменилось. DACL у раздела обновилась. Аргументов у GetSecurityDescriptor как и положено 3:
Кликните здесь для просмотра всего текста

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
'Option Explicit
 
Dim oWMI, oShell, UC
 
Const FILE_WRITE_DATA = 2
Const ACE_ALLOW = 0
Const ACE_DENY = 1
Const HKCU = &H80000001
 
UC = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice"
 
set oShell = CreateObject("WScript.Shell")
 
Set oStdReg = GetObject("winmgmts:{impersonationLevel=Impersonate, (Security)}!\\.\root\default:StdRegProv")
 
Set oWMI = GetObject("winmgmts:\\.\Root\CIMV2")
 
CurSID = oWMI.Get("Win32_UserAccount.Domain='" & oShell.ExpandEnvironmentStrings("%UserDomain%") & "',Name='" & oShell.ExpandEnvironmentStrings("%UserName%") & "'").SID
AdmSID = "S-1-5-32-544"
 
'Set objSD = oWMI.Get("Win32_SecurityDescriptor").SpawnInstance_()
 
ret = oStdReg.GetSecurityDescriptor(HKCU, UC, objSD)
 
If Not IsNull(objSD.DACL) Then
 
    For i = 0 to UBound(objSD.DACL)
 
        SID = objSD.DACL(i).Trustee.SIDString
 
        if ((SID = CurSID) or (SID = AdmSID)) then
 
            if (objSD.DACL(i).AccessMask And FILE_WRITE_DATA) then
 
                if (objSD.DACL(i).AceType = ACE_DENY) then
                    
                    objSD.DACL(i).AceType = ACE_ALLOW
 
                end if
            end if
        end if
    next
end if
 
Result = oStdReg.SetSecurityDescriptor(HKCU, UC, objSD)
 
msgbox "Result = " & Result

На PS просто было приятно отлаживать и смотреть структуры.

Добавлено через 8 минут
Цитата Сообщение от KDE777 Посмотреть сообщение
Dragokas, Вот ещё пример, как к DACL добавляют новую ACE-запись - http://stackoverflow.com/questions/2...rom-powershell
Тоже уже читал
"Те же яйца, только в профиль"

Просто копируется массив структур в другое место. Добавляется новый элемент и копируется обратно.
Естественно, точно та же ошибка, что в посте № 3.

Вот, на всякий, полный код:

Кликните здесь для просмотра всего текста

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$FILE_WRITE_DATA = 2
$ACE_ALLOW = 0
$ACE_DENY = 1
$HKCU = [Uint32]'0x80000001'
 
# Current user's SID
$CurSID = ([wmi] "Win32_userAccount.Domain='$env:UserDomain',Name='$env:UserName'").SID
 
# Administrator's group SID
$AdmSID = "S-1-5-32-544"
 
$UC = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice"
 
$oWMI = get-wmiobject -list "StdRegProv" -namespace 'root\default' -EnableAllPrivileges
 
$SD = $oWMI.GetSecurityDescriptor($HKCU, $UC).Descriptor
 
#.Descriptor
 
# $SD.ControlFlags should contains SE_DACL_PRESENT flag
 
for ($i = 0; $i -lt $SD.DACL.count; $i++)
{
  $SID = $SD.DACL[$i].Trustee.SIDString
  if (($SID -eq $CurSID) -or ($SID -eq $AdmSID))
  {
    if ($SD.DACL[$i].AccessMask -bAnd $FILE_WRITE_DATA)
    {
      if ($SD.DACL[$i].AceType -eq $ACE_DENY)
      {
        $SD.DACL[$i]
        $SD.DACL[$i].Trustee
        $SD.DACL[$i].AceType = $ACE_ALLOW
      }
    }
  }
}
 
$adacl = $sd.DACL
$ace = ([WMIClass]"Win32_ACE").CreateInstance()
$trustee = ([WMIClass]"Win32_Trustee").CreateInstance()
$trustee.Domain = $env:UserDomain
$trustee.Name = $env:UserName
$trustee.SIDString = $CurSID
$ace.Trustee = $trustee
 
$adacl += $ace
$sd.DACL = $adacl
 
$Result = $oWMI.SetSecurityDescriptor($HKCU, $UC, $SD)
$Result
 
$host.ui.RawUI.ReadKey(6)|out-null
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
06.03.2016, 11:04 #6
Цитата Сообщение от Dragokas Посмотреть сообщение
Вот, на всякий, полный код:
Ваш код взгляну попозже, а вот это (если я правильно понял что вам нужно) у меня выполняет вашу задачу:

v0.1 УДАЛИЛ

Добавлено через 3 минуты
Цитата Сообщение от Dragokas Посмотреть сообщение
не знаю, какую роль играет переменная SID у Вас в коде выше, но у меня исключение уже на 6-й строке:
Преобразуется имя локальной группы (или пользователя) $user в sid, возможно у вас это не "everyone", а "все"

Добавлено через 6 часов 21 минуту
Dragokas, вот версия v0.2 более корректная. Всё-таки ночью надо спать...

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$reg = 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice'
$Admins = 'BUILTIN\Администраторы'
$cUser = $env:UserDomain + '\' + $env:UserName
 
$AllowType = [System.Security.AccessControl.AccessControlType]"Allow"
 
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($reg,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$ACL = $key.GetAccessControl()
 
foreach ($ace in $ACL.Access | ?{$_.AccessControlType -eq 'Deny' -and $_.RegistryRights -eq 'SetValue'} | ?{$_.IdentityReference -eq $cUser -or $_.IdentityReference -eq $Admins})
{
    $acl.RemoveAccessRule($ace)
 
    $person = $ace.IdentityReference
    $access = $ace.RegistryRights
    $inheritance = $ace.InheritanceFlags
    $propagation = $ace.PropagationFlags
 
    $AllowRule = New-Object System.Security.AccessControl.RegistryAccessRule($person,$access,$inheritance,$propagation,$AllowType)
    $ACL.AddAccessRule($AllowRule)
}
 
$key.SetAccessControl($ACL)
Добавлено через 45 минут
Цитата Сообщение от Dragokas Посмотреть сообщение
Просто копируется массив структур в другое место. Добавляется новый элемент и копируется обратно.
Естественно, точно та же ошибка, что в посте № 3.
Вот, на всякий, полный код:
Вот для теста код, который добавит в DACL указанной ветки реестра ACE-запись: предоставить текущему пользователю права SetValue

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$HKCU = [Uint32]'0x80000001'
$UC = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice"
 
$CurSID = ([wmi] "Win32_userAccount.Domain='$env:UserDomain',Name='$env:UserName'").SID
$ace = ([WMIClass] "Win32_Ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
$oWMI = get-wmiobject -list "StdRegProv" -namespace 'root\default' -EnableAllPrivileges
$SD = $oWMI.GetSecurityDescriptor($HKCU, $UC).Descriptor
 
$trustee.Domain = $env:UserDomain
$trustee.Name = $env:UserName
$trustee.SIDString = $CurSID
 
$ace.AccessMask = 2
$ace.AceType = 0
$ace.AceFlags = 0
$ace.Trustee = $Trustee
 
$SD.DACL += $ace
$oWMI.SetSecurityDescriptor($HKCU, $UC, $SD)
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
06.03.2016, 17:18  [ТС] #7
Цитата Сообщение от KDE777 Посмотреть сообщение
Вот для теста код, который добавит в DACL указанной ветки реестра ACE-запись: предоставить текущему пользователю права SetValue
Принципиально ничем не отличается. Выводит ту же ошибку из поста № 3.
Цитата Сообщение от KDE777 Посмотреть сообщение
Dragokas, вот версия v0.2 более корректная. Всё-таки ночью надо спать...
Спасибо за альтернативную версию.

Добавлено через 6 минут
Вижу, что работает, только вот вопрос, а как PowerShell оперирует привилегиями.
Ведь для этой операции нужна SeSecurityPrivilege. В моих вариантах я ее явно устанавливаю.
А через класс [Microsoft.Win32.Registry] получается он автоматически ее затребует?
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
07.03.2016, 00:08 #8
Цитата Сообщение от Dragokas Посмотреть сообщение
Принципиально ничем не отличается. Выводит ту же ошибку из поста № 3.
Протестировал - эта ошибка возникает в PS 2.0, а в 3 и выше уже нет.

$ace - System.Management.ManagementObject#\Win32_ACE
$SD.DACL[0] - System.Management.ManagementBaseObject#\__ACE

Вот PS2 и не справляется с сопоставлением этих типов...

Цитата Сообщение от Dragokas Посмотреть сообщение
Ведь для этой операции нужна SeSecurityPrivilege.
Если попытаться применить модифицированный $ACL, через - $ACL | Set-Acl -Path RegPath, то не смотря на запуск от имени владельца этой ветки, PS выдаст ошибку - Requested registry access is not allowed, поэтому приходится использовать конструкцию:

[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey
+
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree
[System.Security.AccessControl.RegistryRights]::ChangePermissions

А вот, например для изменения разрешений файлов и папок отлично хватает - Get-ACL и Set-ACL, но тоже только подобным способом - создаётся нужная ACE-запись и добавляется в ACL (а не нужная удаляется), после чего весь изменённый ACL применяется (Set-ACL) к объекту. Попытка напрямую поменять (присвоить) что-то в считанной (через Get-ACL) ACE-записи вызовет read only ошибку...
1
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
07.03.2016, 00:48  [ТС] #9
Спасибо. Познавательно.
А PS 3.0 он в коробке идет с какой версией ОС?
Цитата Сообщение от KDE777 Посмотреть сообщение
$SD.DACL
А можно ли попытаться как-то просто увеличить размерность массива (без присвоения нового элемента) ?
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
07.03.2016, 02:07 #10
Цитата Сообщение от Dragokas Посмотреть сообщение
А PS 3.0 он в коробке идет с какой версией ОС?
PS 3.0 появился в Win8/2012, но можно поставить и на Wn7SP1/2008R2 - https://www.microsoft.com/en-us/download/details.aspx?id=34595

Цитата Сообщение от Dragokas Посмотреть сообщение
А можно ли попытаться как-то просто увеличить размерность массива (без присвоения нового элемента) ?
Размерность массива равна количеству его элементов - $SD.DACL.Length - а вы хотите, чтобы у массива с 2 элементами длинна стала 3? А зачем?

Как это сделать не знаю и не уверен, что вообще возможно. Например, попытка присвоить пустой элемент $SD.DACL += $null - не работает...

Можно создать пустой массив нулевой длинны:

PowerShell
1
2
$a = @()
$a.Length
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
07.03.2016, 02:26  [ТС] #11
KDE777, хотел обойти ограничение +=. Сначала увеличив размерность, а затем сделав присвоение последнему элементу.
Но похоже PS оперирует какими-то странными структурами и перегрузками методов WMI (нигде кроме самого PS не описанными официально), где часть полей являются Read-Only. При чем запись в это поле не вызывает исключения на сколько я убедился судя из этой темы.

Добавлено через 2 минуты
Попробую чуть позже тоже самое на PS 3.0, может это у них баг такой.
0
greg zakharov
Покинул форум
1947 / 823 / 236
Регистрация: 07.05.2015
Сообщений: 1,645
07.03.2016, 09:27 #12
Dragokas, а обозревателями объектов WMI не пользовались? Например:
Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#requires -version 2.0
{
  Add-Type -AssemblyName System.Windows.Forms
  
  if (!(New-Object Security.Principal.WindowsPrincipal (
    [Security.Principal.WindowsIdentity]::GetCurrent()
  )).IsInRole(
    [Security.Principal.WindowsBuiltInRole]::Administrator
  )) {
    [void][Windows.Forms.MessageBox]::Show(
        "WMIExplorer requires administrator privileges.",
        "WMIExplorer",
        [Windows.Forms.MessageBoxButtons]::OK,
        [Windows.Forms.MessageBoxIcon]::Information
    )
    return
  }
  
  [Windows.Forms.Application]::EnableVisualStyles()
  $ico = [Drawing.Icon]::ExtractAssociatedIcon("$PSHome\powershell.exe")
  $f_1 = New-Object Drawing.Font("Tahoma", 9, [Drawing.FontStyle]::Bold)
  $f_2 = New-Object Drawing.Font("Tahoma", 8, [Drawing.FontStyle]::Bold)
  $i_1 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAA" + `
         "AgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAEJJREFUOE9j/P//PwNJAKiBJMCArBpuE0QQjQsVhGuASGPahiaOUDG0NWANDVyhN1w8jRbZ8PgmkD" + `
         "SITIJYEg9+nQBeQy7v217GjAAAAABJRU5ErkJggg=="
  $i_2 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAA" + `
         "AgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRF////9u7YW5vY4+74rbfE4aoU/ez99u/a0mXT9+/bb4CXADOZgWIMjC2NnngO/fD9mc3//e" + `
         "39+q3623DcyJgX89Zs+pj79eGF8ctQ8stQ78A04t73fLTpNWO17fT67bUc2GzZ9Ndr7rUd8MA17bUdsjyz9eCF9OGG5/D56vL68ctP7rYc9NZrQ" + `
         "3PJ9eGG774v8MA06fH5////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrgGBQAAAJJJREFUKFNVjtcSgzAMBM/ggh1KGqGl917+/" + `
         "+ciGwJEL5pdnWYOoNGC2dWOFtm0b7Q43XNnEpfR4pgW5T5kSAJrmHimxW5FLINxIAGRbfL3tubZJBqBxdfyFRpj1jUDKr7FChzyULM1CiQgo6pp" + `
         "QmwFKu/SlSPhe8PHuTXc8twb+D/DzT+TXy56d5f7dPnmz/1/Ab2bB7l4ZZdYAAAAAElFTkSuQmCC"
  $i_3 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAA" + `
         "AgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRF475Q7NKHZ3qVrpuB69GF5cNZ69Fz58hk8uGPeoym6tFy4sRx5cVc7dZ89OaZ4r1P58x8hm" + `
         "xH9+2m3Lxk7th/8d6J6s9v4LdE9OeZ8uORy8Cz9eug69J19uufnYhu6ctpb4Gc9+3P5cNa4tGp6cpn79yFtKSKpZF39OaYzKIxeouneFw6boGb7" + `
         "9uDgWZD8eCOn4he2b9plX5kmYRqel48d1o569CEfWJA7NR5vKyS37hJoo5079uFnolw////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + `
         "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK4belAAAAHtJREFUKFNjsEMDDEQLKDIwsghwC2sqw7QwC" + `
         "ElLSIqKyAjCBWT5tBSY2OT1YAKMGhyqvFwqPOYMdjDdhpw6TEoMJgx2cN1i7Kz84qYMdoxQ3dZqzOpy2lJAAahuW4gTGezM9G3Auo1hAla6FmDd" + `
         "RjABZQNLiG6YACHfAgASrCzzMRTKjwAAAABJRU5ErkJggg=="
  
  function Get-Resource([String]$s) {
    [Drawing.Image]::FromStream(
      (New-Object IO.MemoryStream(($$ = [Convert]::FromBase64String($s)), 0, $$.Length))
    )
  }
  
  function Get-NameSpaces([String]$root) {
    (New-Object Management.ManagementClass(
        $root, [Management.ManagementPath]'__NAMESPACE', $null
      )
    ).PSBase.GetInstances() | % {
      return (New-Object Windows.Forms.TreeNode).Nodes.Add($_.Name)
    }
  }
  
  function Get-SubNameSpace([Windows.Forms.TreeNode[]]$nodes) {
    foreach ($nod in $nodes) {
      $nod.Nodes.Clear()
      Get-NameSpaces ('root\' + $nod.FullPath) | % { $nod.Nodes.Add($_) }
    }
  }
  
  function Get-ClassesNumber {
    $sbLbl_1.Text = "Classes: " + $lvList1.Items.Count.ToString()
  }
  
  function Reset-AllMessages {
    $lvList2.Items.Clear()
    $rtbDesc, $sbLbl_2, $sbLbl_3 | % { $_.Text = [String]::Empty }
  }
  
  function Get-Description([Object]$o, [Boolean]$b) {
    try {
      $$ = switch ($b) { $true { [Management.MethodData]$o } $false { [Management.PropertyData]$o } }
      $$ = $$.PSBase.Qualifiers['Description'].Value
      $$ = $(if (![String]::IsNullOrEmpty($$)) { $$ } else { "n\a" }) + "`n`n"
    }
    catch {}
    
    return $$
  }
  
  $frmMain = New-Object Windows.Forms.Form
  $mnuMain = New-Object Windows.Forms.MenuStrip
  $mnuFile = New-Object Windows.Forms.ToolStripMenuItem
  $mnuExit = New-Object Windows.Forms.ToolStripMenuItem
  $mnuView = New-Object Windows.Forms.ToolStripMenuItem
  $mnuSStr = New-Object Windows.Forms.ToolStripMenuItem
  $mnuHelp = New-Object Windows.Forms.ToolStripMenuItem
  $mnuInfo = New-Object Windows.Forms.ToolStripMenuItem
  $scSplt1 = New-Object Windows.Forms.SplitContainer
  $scSplt2 = New-Object Windows.Forms.SplitContainer
  $tvRoots = New-Object Windows.Forms.TreeView
  $lvList1 = New-Object Windows.Forms.ListView
  $lvList2 = New-Object Windows.Forms.ListView
  $chCol_1 = New-Object Windows.Forms.ColumnHeader
  $chCol_2 = New-Object Windows.Forms.ColumnHeader
  $chCol_3 = New-Object Windows.Forms.ColumnHeader
  $chCol_4 = New-Object Windows.Forms.ColumnHeader
  $chCol_5 = New-Object Windows.Forms.ColumnHeader
  $chCol_6 = New-Object Windows.Forms.ColumnHeader
  $chCol_7 = New-Object Windows.Forms.ColumnHeader
  $tabCtrl = New-Object Windows.Forms.TabControl
  $tpPage1 = New-Object Windows.Forms.TabPage
  $tpPage2 = New-Object Windows.Forms.TabPage
  $rtbDesc = New-Object Windows.Forms.RichTextBox
  $imgList = New-Object Windows.Forms.ImageList
  $sbStrip = New-Object Windows.Forms.StatusStrip
  $sbLbl_1 = New-Object Windows.Forms.ToolStripStatusLabel
  $sbLbl_2 = New-Object Windows.Forms.ToolStripStatusLabel
  $sbLbl_3 = New-Object Windows.Forms.ToolStripStatusLabel
  #common
  $mnuMain.Items.AddRange(@($mnuFile, $mnuView, $mnuHelp))
  $scSplt1, $scSplt2, $tvRoots, $lvList1, $lvList2, $tabCtrl, $rtbDesc | % {
    $_.Dock = [Windows.Forms.DockStyle]::Fill
  }
  $scSplt1, $scSplt2 | % { $_.SplitterWidth = 1 }
  $lvList1, $lvList2 | % {
    $_.FullRowSelect = $true
    $_.MultiSelect = $false
    $_.ShowItemToolTips = $true
    $_.Sorting = [Windows.Forms.SortOrder]::Ascending
  }
  $chCol_1.Text = "Name"
  $chCol_2.Text = "Desciption"
  $chCol_3.Text = "Amended"
  $chCol_4.Text = "Local"
  $chCol_5.Text = "Overridable"
  $chCol_6.Text = "PropagatesToInstance"
  $chCol_7.Text = "PropagatesToSubclass"
  $chCol_1, $chCol_2, $chCol_6, $chCol_7 | % { $_.Width = 130 }
  $chCol_3, $chCol_4, $chCol_5 | % { $_.Width = 70 }
  $tabCtrl.Controls.AddRange(@($tpPage1, $tpPage2))
  $tpPage1, $tpPage2 | % { $_.UseVisualStyleBackColor = $true }
  $rtbDesc.ReadOnly = $true
  $i_1, $i_2, $i_3 | % { $imgList.Images.Add((Get-Resource $_)) }
  $sbStrip.Items.AddRange(@($sbLbl_1, $sbLbl_2, $sbLbl_3))
  $sbLbl_1, $sbLbl_2, $sbLbl_3 | % { $_.AutoSize = $true }
  $sbLbl_2.ForeColor = [Drawing.Color]::DarkMagenta
  $sbLbl_3.ForeColor = [Drawing.Color]::DarkGreen
  #mnuFile
  $mnuFile.DropDownItems.AddRange(@($mnuExit))
  $mnuFile.Text = "&File"
  #mnuExit
  $mnuExit.ShortcutKeys = [Windows.Forms.Keys]::Control, [Windows.Forms.Keys]::X
  $mnuExit.Text = "E&xit"
  $mnuExit.Add_Click({$frmMain.Close()})
  #mnuView
  $mnuView.DropDownItems.AddRange(@($mnuSStr))
  $mnuView.Text = "&View"
  #mnuSStr
  $mnuSStr.Checked = $true
  $mnuSStr.Text = "&Status Bar"
  $mnuSStr.Add_Click({
    $toggle =! $mnuSStr.Checked
    $mnuSStr.Checked = $toggle
    $sbStrip.Visible = $toggle
  })
  #mnuHelp
  $mnuHelp.DropDownItems.AddRange(@($mnuInfo))
  $mnuHelp.Text = "&Help"
  #mnuInfo
  $mnuInfo.Text = "About..."
  $mnuInfo.Add_Click({
    $frmInfo = New-Object Windows.Forms.Form
    $pbImage = New-Object Windows.Forms.PictureBox
    $lblName = New-Object Windows.Forms.Label
    $lblCopy = New-Object Windows.Forms.Label
    $btnExit = New-Object Windows.Forms.Button
    #
    #pbImage
    #
    $pbImage.Image = $ico.ToBitmap()
    $pbImage.Location = New-Object Drawing.Point(16, 16)
    $pbImage.Size = New-Object Drawing.Size(32, 32)
    $pbImage.SizeMode = [Windows.Forms.PictureBoxSizeMode]::StretchImage
    #
    #lblName
    #
    $lblName.Font = $f_2
    $lblName.Location = New-Object Drawing.Point(53, 19)
    $lblName.Size = New-Object Drawing.Size(360, 18)
    $lblName.Text = "WMIExplorer v1.01"
    #
    #lblCopy
    #
    $lblCopy.Location = New-Object Drawing.Point(67, 37)
    $lblCopy.Size = New-Object Drawing.Size(360, 23)
    $lblCopy.Text = "Copyright (C) 2011-2014 greg zakharov"
    #
    #btnExit
    #
    $btnExit.Location = New-Object Drawing.Point(135, 67)
    $btnExit.Text = "OK"
    #
    #frmInfo
    #
    $frmInfo.AcceptButton = $btnExit
    $frmInfo.CancelButton = $btnExit
    $frmInfo.ClientSize = New-Object Drawing.Size(350, 110)
    $frmInfo.ControlBox = $false
    $frmInfo.Controls.AddRange(@($pbImage, $lblName, $lblCopy, $btnExit))
    $frmInfo.FormBorderStyle = [Windows.Forms.FormBorderStyle]::FixedSingle
    $frmInfo.ShowInTaskbar = $false
    $frmInfo.StartPosition = [Windows.Forms.FormStartPosition]::CenterParent
    $frmInfo.Text = "About..."
    
    [void]$frmInfo.ShowDialog()
  })
  #scSplt1
  $scSplt1.Orientation = [Windows.Forms.Orientation]::Horizontal
  $scSplt1.Panel1.Controls.Add($scSplt2)
  $scSplt1.Panel2.Controls.Add($tabCtrl)
  $scSplt1.SplitterDistance = 60
  #scSplt2
  $scSplt2.Panel1.Controls.Add($tvRoots)
  $scSplt2.Panel2.Controls.Add($lvList1)
  $scSplt2.Panel1MinSize = 17
  $scSplt2.SplitterDistance = 30
  #tvRoots
  $tvRoots.ImageList = $imgList
  $tvRoots.Select()
  $tvRoots.Sorted = $true
  $tvRoots.Add_AfterExpand({Get-SubNameSpace $_.Node.Nodes})
  $tvRoots.Add_AfterSelect({
    $lvList1.Items.Clear()
    Reset-AllMessages
    
    if ($tvRoots.SelectedNode) {
      $cur = 'root\' + $tvRoots.SelectedNode.FullPath
      
      (New-Object Management.ManagementClass($cur, $obj)
      ).PSBase.GetSubclasses($enm) | % {
        $lvList1.Items.Add($_.Name, 1)
      }
      
      $frmMain.Text = $cur + ' - WMIExplorer'
      Get-ClassesNumber
    } #if
  })
  #lvList1
  $lvList1.LargeImageList = $imgList
  $lvList1.TileSize = New-Object Drawing.Size(270, 19)
  $lvList1.View = [Windows.Forms.View]::Tile
  $lvList1.Add_Click({
    Reset-AllMessages
    
    for ($i = 0; $i -lt $lvList1.Items.Count; $i++) {
      if ($lvList1.Items[$i].Selected) {
        $path = $cur + ':' + $lvList1.Items[$i].Text
        $frmMain.Text = $path + ' - WMIExplorer'
        $rtbDesc.SelectionFont = $f_1
        $rtbDesc.AppendText("$($lvList1.Items[$i].Text)`n$(('-' * 100))`n")
        $wmi = (New-Object Management.ManagementClass($path, $obj)).PSBase
        $wmi.Qualifiers | % {
          $itm = $lvList2.Items.Add($_.Name, 2)
          if ($_.Name -match 'Description') {
            $rtbDesc.AppendText("$($_.Value)`n`n")
            $itm.SubItems.Add("See specification")
          }
          else { $itm.SubItems.Add($_.Value.ToString()) }
          $itm.SubItems.Add($_.IsAmended.ToString())
          $itm.SubItems.Add($_.IsLocal.ToString())
          $itm.SubItems.Add($_.IsOverridable.ToString())
          $itm.SubItems.Add($_.PropagatesToInstance.ToString())
          $itm.SubItems.Add($_.PropagatesToSubclass.ToString())
        }
        $wmi.Methods | % {
          $rtbDesc.SelectionColor = [Drawing.Color]::DarkMagenta
          $rtbDesc.SelectionFont = $f_2
          $rtbDesc.AppendText("$($_.Name)`n")
          $rtbDesc.AppendText((Get-Description $_ $true))
        }
        $wmi.Properties | % {
          $rtbDesc.SelectionColor = [Drawing.Color]::DarkGreen
          $rtbDesc.SelectionFont = $f_2
          $rtbDesc.AppendText("$($_.Name + '(Type: ' + $_.Type + ', Local: ' + $_.IsLocal + ', Array: ' + $_.IsArray + ')')`n")
          $rtbDesc.AppendText((Get-Description $_ $false))
        }
        if ($wmi.Derivation.Count -ne 0) {
          $rtbDesc.SelectionColor = [Drawing.Color]::DarkBlue
          $rtbDesc.SelectionFont = $f_2
          $rtbDesc.AppendText("Derivation`n")
          $wmi.Derivation | % { $rtbDesc.AppendText("$($_)`n") }
        }
        $sbLbl_2.Text = "Methods: " + $wmi.Methods.Count.ToString()
        $sbLbl_3.Text = "Properties: " + $wmi.Properties.Count.ToString()
      } #if
    } #for
  })
  #lvList2
  $lvList2.Columns.AddRange(@($chCol_1, $chCol_2, $chCol_3, $chCol_4, $chCol_5, $chCol_6, $chCol_7))
  $lvList2.SmallImageList = $imgList
  $lvList2.View = [Windows.Forms.View]::Details
  #tpPage1
  $tpPage1.Controls.AddRange(@($rtbDesc))
  $tpPage1.Text = "Specification"
  #tpPage2
  $tpPage2.Controls.AddRange(@($lvList2))
  $tpPage2.Text = "Qualifiers"
  #frmMain
  $frmMain.ClientSize = New-Object Drawing.Size(800, 557)
  $frmMain.Controls.AddRange(@($scSplt1, $sbStrip, $mnuMain))
  $frmMain.Icon = $ico
  $frmMain.MainMenuStrip = $mnuMain
  $frmMain.StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen
  $frmMain.Text = "WMIExplorer"
  $frmMain.Add_Load({
    Get-NameSpaces 'root' | % { $tvRoots.Nodes.Add($_) }
    Get-SubNameSpace $tvRoots.Nodes
    
    $obj = New-Object Management.ObjectGetOptions
    $enm = New-Object Management.EnumerationOptions
    
    $obj.UseAmendedQualifiers = $enm.EnumerateDeep = $true
    $sbLbl_1.Text = "Ready"
  })
  
  [void]$frmMain.ShowDialog()
}.Invoke()
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
07.03.2016, 11:39 #13
Цитата Сообщение от Dragokas Посмотреть сообщение
хотел обойти ограничение +=. Сначала увеличив размерность, а затем сделав присвоение последнему элементу.
Так у вас проблема с несовпадением типов. В $ace хранится объект: System.Management.ManagementObject, а в $SD.DACL объекты: System.Management.ManagementBaseObject

А механизм расширение массива, думаю у вас работает без всяких проблем:
Кликните здесь для просмотра всего текста

PowerShell
1
2
3
4
$a = 'abcd'.ToCharArray()
$a;$a.Length
$a += 'e'
$a;$a.Length


Цитата Сообщение от Dragokas Посмотреть сообщение
Попробую чуть позже тоже самое на PS 3.0, может это у них баг такой.
А чем не устраивает мой вариант? По моему, он более наглядный и удобный - тип разрешений, права, пользователи указаны без всяких кодов и sid'ов + работает у вас без ошибок. А вариант с $SD.DACL += $ace, если и заработает, то это только добавление нужной ACE-записи, после чего понадобится ещё удалить из $SD.DACL запрещающую ACE-запись...

Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$reg = 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.zip\UserChoice'
$Admins = 'BUILTIN\Администраторы'
$cUser = $env:UserDomain + '\' + $env:UserName
 
$AllowType = [System.Security.AccessControl.AccessControlType]"Allow"
 
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($reg,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$ACL = $key.GetAccessControl()
 
foreach ($ace in $ACL.Access | ?{$_.AccessControlType -eq 'Deny' -and $_.RegistryRights -eq 'SetValue'} | ?{$_.IdentityReference -eq $cUser -or $_.IdentityReference -eq $Admins})
{
    $acl.RemoveAccessRule($ace)
 
    $person = $ace.IdentityReference
    $access = $ace.RegistryRights
    $inheritance = $ace.InheritanceFlags
    $propagation = $ace.PropagationFlags
 
    $AllowRule = New-Object System.Security.AccessControl.RegistryAccessRule($person,$access,$inheritance,$propagation,$AllowType)
    $ACL.AddAccessRule($AllowRule)
}
 
$key.SetAccessControl($ACL)
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,868
Записей в блоге: 16
07.03.2016, 14:13  [ТС] #14
greg zakharov, спасибо. Прикольный обозреватель.
Но он пишет:
GetSecurityDescriptor
The GetSecurityDescriptor method returns the specified key's security descriptor in a __SecurityDescriptor. The method returns a uint32 which is 0 if successful or some other value if any other error occurred.
А в 1-м посте убеждаемся, что возвращается объект. Хотя я и не исключаю, что что-то делаю неправильно.
Цитата Сообщение от KDE777 Посмотреть сообщение
А механизм расширение массива, думаю у вас работает без всяких проблем:
Да.
Цитата Сообщение от KDE777 Посмотреть сообщение
А чем не устраивает мой вариант?
Устраивает. Но мне интересно с академической целью. В VBcript работает. Здесь тоже должен.
Цитата Сообщение от KDE777 Посмотреть сообщение
А вариант с $SD.DACL += $ace, если и заработает, то это только добавление нужной ACE-записи, после чего понадобится ещё удалить из $SD.DACL запрещающую ACE-запись...
Ну изначально я хотел сразу поменять флаг, но он оказался ReadOnly (вроде).
На счет удалить запрещающую - заинтересовало. А вот можно ли как-то в PS удалить элемент массива?
Цитата Сообщение от KDE777 Посмотреть сообщение
Так у вас проблема с несовпадением типов. В $ace хранится объект: System.Management.ManagementObject, а в $SD.DACL объекты: System.Management.ManagementBaseObject
Тут оказалось проблема гораздо глубже.
Добавьте к коду из 1-го поста вот это:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
echo "Add element without modifications"
echo .
echo ('DACL Ubound = ' + $SD.DACL.count)
echo .
$Dacl_2 = $SD.DACL[0]
$SD.DACL += $Dacl_2
 
echo ('DACL Ubound = ' + $SD.DACL.count)
echo .
echo "Modify .AceType"
echo .
echo ('DACL Ubound = ' + $SD.DACL.count)
 
$Dacl_2.AceType = 0
echo ('$SD.DACL[0].AceType = ' + $SD.DACL[0].AceType)
echo ('$Dacl_2.AceType = ' + $Dacl_2.AceType)
$SD.DACL += $Dacl_2
 
echo ('DACL Ubound = ' + $SD.DACL.count)
 
$Dacl_2.GetType().fullname
$SD.DACL[0].GetType().fullname
$SD.DACL.GetType().fullname
Здесь я просто копирую элемент массива, чтобы не было со стороны интерпретатора претензий на счет несовпадающего типа данных.
Так вот, если структуру не изменять, то она прекрасно делает инкремент к массиву.
Если хоть одно поле изменить, то при добавлении такого элемента к массиву получаем ошибку:

Код
Add element without modifications
.
DACL Ubound = 38
.
DACL Ubound = 39
.
Modify .AceType
.
DACL Ubound = 39
$SD.DACL[0].AceType = 1
$Dacl_2.AceType = 0
Исключение при задании "DACL" : "Не удалось привести тип объекта "System.Management.Automation.PSObject" к типу "System
.Management.ManagementBaseObject"."
H:\_Powershell\EnumRegAccess.ps1:54 знак:5
+ $SD. <<<< DACL += $Dacl_2
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

DACL Ubound = 39
System.Management.ManagementBaseObject
System.Management.ManagementBaseObject
System.Management.ManagementBaseObject[]
При этом SetSecurityDescriptor успешно записывает такой дескриптор. При повторном запуске кода кол-во записей ACE становится больше на +1.
Получается, система делает какую-то проверку на "корректность" данных в структуре.

Добавлено через 1 час 11 минут
Вообщем провел я последний тест на PS 3.0, 4.0, 5.0.
Ошибки там уже нет. Похоже это какая-то бага PS 2.0.

Также я проверил можно ли изменить напрямую поле .AceType сразу после получения дескриптора.
Оказалось что тоже нельзя
Значение не меняется. Исключений тоже нет.
0
KDE777
717 / 532 / 229
Регистрация: 22.01.2016
Сообщений: 1,492
08.03.2016, 02:38 #15
Цитата Сообщение от Dragokas Посмотреть сообщение
На счет удалить запрещающую - заинтересовало. А вот можно ли как-то в PS удалить элемент массива?
В моём примере - $ACL.RemoveAccessRule($ace) - как раз удаляет указанную ACE-запись из этого ACL. Ещё можем удалять сразу все явно заданные ACE-записи определённого пользователя или группы - $ACL.PurgeAccessRules([System.Security.Principal.NTAccount]'mydomain\user')

Но это всё методы объекта - System.Security.AccessControl.RegistrySecurity

Если интересует, как удалить элемент из обычного массива (System.Array), то только через создание нового массива без ненужных элементов + можно использовать специальный тип массива System.Collections.ArrayList

Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
$A = 'abcde'.ToCharArray()
$A1 = $A | ?{$_ -ne 'c'}
$A2 = $A[0,2,3]
Write-Host 'A:' $A
Write-Host 'A1:' $A1
Write-Host 'A2:' $A2
 
[System.Collections.ArrayList]$A = 'a','b','c','d','e'
$A.Remove('d')
$A.RemoveAt(1)
Write-Host 'A:' $A
1
08.03.2016, 02:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.03.2016, 02:38

Не изменяется ветка реестра LOCAL_MACHINE
Помогите пожалуйста. Не хочет ветка изменяться. Когда пробую другую ветку,...

Программа, создающая таблицу имен из раздела констант, содержащую следующие поля: имя, значение, тип, число обращений
программа создающая таблицу имен из раздела констант, содержащую следующие...

При изменении содержимого 1-го поля изменяется содержимое 2-го текстового поля.
На Web-форме имеются два текстовых поля. При изменении содержимого 1-го поля...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru