2013-03-11 2 views
0

특정 값에 대해 레지스트리를 통과하는 스크립트에 도움이 필요합니다. 일치하는 항목이 있으면 상위 키를 삭제하십시오. 코드를 찾았지만 작동하지 않습니다. 나는 그것이 일치하는 레지스트리 키를 통과하지 못하고 있다고 생각한다.일치하는 값이 있으면 레지스트리를 검색하십시오. 부모 키를 삭제하십시오.

Option Explicit 

Const HKEY_LOCAL_MACHINE = &H80000002 
Const cRegKeyStartingPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" 
Const cRegValueToFind  = "Ossec HIDS" 
Const cRegDataToMatch  = "DisplayName" 

Dim oReg, subkey, arrSubKeys, sCurrentKey, sCurrentValuePath, iDeletedCount 
iDeletedCount = 0 

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") 
oReg.EnumKey HKEY_LOCAL_MACHINE, cRegKeyStartingPath, arrSubKeys 

On Error Resume Next 
For Each subkey In arrSubKeys 
    If Err.Number = 0 Then 'in case the collection is empty 
     sCurrentKey = "HKLM\" & cRegKeyStartingPath & subkey 
     sCurrentValuePath = sCurrentKey & "\" & cRegValueToFind 
     If customRegRead(sCurrentValuePath) = cRegDataToMatch Then 
      WScript.Echo "Going to delete "&sCurrentKey 
      DeleteRegKey sCurrentKey&"\" 
      iDeletedCount = iDeletedCount + 1 
     End If 
    Else 
     iDeletedCount = -1 
    End If 
Next 

Select Case iDeletedCount 
    Case 0 
     WScript.Echo "No matching keys found" 
    Case -1 
     WScript.Echo "No subkeys found below HKLM\"&cRegKeyStartingPath 
    Case Else 
     WScript.Echo "Deleted " & iDeletedCount & " keys" 
End Select 

Function customRegRead(sRegValue) 

    Dim oShell 
    Dim sRegReturn 

    Set oShell = CreateObject("WScript.Shell") 

    On Error Resume Next 
    Err.Clear 
    sRegReturn = oShell.RegRead(sRegValue) 
    If Err.Number<>0 Then 
     customRegRead = "Failed To Read Value" 
    Else 
     customRegRead = sRegReturn 
    End If 

End Function 

Sub DeleteRegKey(sKey) 

    Dim oShell 
    Set oShell = CreateObject("Wscript.Shell") 
    oShell.RegDelete sKey 

End Sub 

더 깨끗한 것이 있으면/더 자세히 알려주십시오.

+1

'cRegKeyStartingPath'가 레지스트리의 유효한 위치를 가리키고 있는지 확인 했습니까? 내 컴퓨터 (Windows 7)에는 'Windows'대신 'Windows NT'가 있습니다.또한 디버깅 할 때'On Error' 문을 끄는 것이 좋습니다. 예기치 않은 오류가 있으면 도움이됩니다. – Floris

+0

CRegKeystartingpath가 유효합니다. 나는 코드를 작성하지 않지만 이것이 하위 키를 통과하지 않는다고 생각합니다. – user347258

+2

코드 작성에 경험이 없다면, 내가 이해하지 못하는 코드를 사용하여 레지스트리에 액세스/수정하지 말 것을 권할 것입니다. – Floris

답변

2

나는 모든 On Error Resume Next을 제거하고 WMI 방법을 고수하고 싶습니다. 또한 현재 코드는 재귀를 사용하지 않으므로 바로 하위 키 cRegKeyStartingPath에서만 값을 찾을 수 있습니다. 당신은 임의의 깊이의 나무를 가로 지르는 재귀가 필요합니다.

rc = reg.EnumValues(HKLM, key, names, types) 

방법이 성공하면 0 반환, 그래서 당신은 리턴 코드를 평가하여 오류를 확인할 수 있습니다

사용 EnumValues는 주어진 키의 값을 열거합니다. 호출이 완료된 후 names 변수의 값은 key 또는 Null의 값을 갖는 배열을 포함합니다 (기본값보다 작은 경우). 그래서 특정 값은 다음과 같을 수 주어진 키에 존재하는지 확인하기위한 코드 :

: 당신은 그 하위에 EnumKey를 통해 지정된 키의 하위 키를 열거하고 재귀하여 레지스트리를 통과 할 수

reg.EnumValues HKLM, key, names, types 
If Not IsNull(names) Then 
    For Each name In names 
    If name = "foo" Then 
     reg.GetStringValue HKLM, key, name, data 
     If data = "bar" Then 
     'delete key here 
     Exit For 
     End If 
    End If 
    Next 
End If 

Sub TraverseRegistry(root, key) 
    reg.EnumKey root, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     TraverseRegistry root, key & "\" & sk 
    Next 
    End If 
End Sub 

키를 삭제하려면 DeleteKey 메서드를 사용하십시오. 키를 삭제해야하는 정보는 이미 가지고있는 것입니다. 즉, 이 true 일 때 값 열거 루틴의 변수 key의 값입니다. 그러나 하위 키가있는 키는 삭제할 수 없으므로 을 먼저 삭제해야합니다.. 당신이 위에서 순회 루틴을 다시 사용할 수있는 뭔가 :

Sub DelKey(root, key) 
    reg.EnumKey root, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     DelKey root, key & "\" & sk 'delete subkeys first 
    Next 
    End If 
    'at this point all subkeys have already been deleted, so we can 
    'now delete the parent key 
    reg.DeleteKey root, key 
End Sub 

넣어 모든 것을 함께 하고이 같은 것을 얻을 :

Const HKLM = &h80000002 

Const StartKey = "SOFTWARE\Wow...ion\Uninstall" 
Const SearchValue = "DisplayName" 
Const MatchData = "Ossec HIDS" 

Set reg = GetObject("winmgmts://./root/default:StdRegProv") 

FindAndDeleteKey HKLM, StartKey, SearchValue, MatchData 

Sub FindAndDeleteKey(root, key, value, data) 
    reg.EnumValues HKLM, key, names, types 
    If Not IsNull(names) Then 
    For Each name In names 
     If name = value Then 
     reg.GetStringValue HKLM, key, name, regdata 
     If regdata = data Then 
      DelKey root, key 
      Exit Sub 
     End If 
     End If 
    Next 
    End If 

    'value not found in current key => continue search in subkeys 
    reg.EnumKey root, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     FindAndDeleteKey root, key & "\" & sk, value, data 
    Next 
    End If 
End Sub 

Sub DelKey(root, key) 
    reg.EnumKey root, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     DelKey root, key & "\" & sk 'delete subkeys first 
    Next 
    End If 
    'at this point all subkeys have already been deleted, so we can 
    'now delete the parent key 
    reg.DeleteKey root, key 
End Sub 

당신이 특정 데이터에 특정 값을 찾고 있기 때문에 당신은이에 FindAndDeleteKey()을 단순화 수 :

Sub FindAndDeleteKey(key) 
    'Try to read the value directly. If the value doesn't exist this will 
    'simply return a non-zero return code and set data to Null. 
    reg.GetStringValue HKLM, key, SearchValue, data 
    If Not IsNull(data) Then 
    'value does exist 
    If data = MatchData Then 
     DelKey HKLM, key 
     Exit Sub 
    End If 
    End If 

    'value not found in current key => continue search in subkeys 
    reg.EnumKey HKLM, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     FindAndDeleteKey key & "\" & sk 
    Next 
    End If 
End Sub 

편집 : 다음은 일부 디버그 출력을 생성하는 버전입니다. 명령 프롬프트에서 cscript debug_sample.vbs을 통해 실행하십시오. HKLM에서 내용을 삭제하려는 경우 이어야하며 UAC가 활성화되면 "관리자 권한으로"스크립트를 실행해야합니다.

Const HKLM = &h80000002 

Const StartKey = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" 
Const SearchValue = "DisplayName" 
Const MatchData = "Ossec HIDS" 

Set reg = GetObject("winmgmts://./root/default:StdRegProv") 

FindAndDeleteKey StartKey 

Sub FindAndDeleteKey(key) 
    WScript.Echo "[HKLM\" & key & "]" 
    rc = reg.GetStringValue(HKLM, key, SearchValue, data) 
    If Not IsNull(data) Then 
    WScript.Echo """" & SearchValue & """=""" & data & """" 
    If data = MatchData Then 
     DelKey HKLM, key 
     Exit Sub 
    End If 
    Else 
    WScript.Echo "'" & SearchValue & "' not found in [HKLM\" & key & "], rc=" & rc 
    End If 

    reg.EnumKey HKLM, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     FindAndDeleteKey key & "\" & sk 
    Next 
    End If 
End Sub 

Sub DelKey(root, key) 
    reg.EnumKey root, key, subkeys 
    If Not IsNull(subkeys) Then 
    For Each sk In subkeys 
     DelKey root, key & "\" & sk 
    Next 
    End If 
    rc = reg.DeleteKey(root, key) 
    WScript.Echo "Deleting [HKLM\" & key & "], rc=" & rc 
End Sub 

는 I 잘못된 hDefKey 값, 예를 들어 함께 리턴 코드 6 (핸들이 무효) 재현 할 수 있었다 &h8000002 (7 자리 숫자 만) 또는 h80000002 (앰퍼샌드 없음).

+0

스크립트에 대한 와우 감사와 고장 및 설명. 그러나 스크립트를 실행하여 레지스트리 키를 삭제할 수는 없습니다. 내가 뭔가 잘못하고있다. – user347258

+0

@ user347258 정보없이 알기가 어렵다. 나는 메소드의 반환 코드, 특히'DeleteKey'를 확인하는 것으로 시작합니다 :'rc = reg.DeleteKey root, key : WScript.Echo key & ":"& rc'. 단순성을 위해 샘플 코드에서 해당 검사를 생략했습니다. 비교 대상 문자열의 철자가 올바른지 확인하십시오. 샘플 코드의 수표는 대소 문자를 구분합니다. 또한 선행/후행 공백을 검사하거나 제거하십시오 ('Trim()'). 아래의 –

+0

은 레지스트리 내보내기의 트림 된 버전입니다. [HKEY_LOCAL_MACHINE \ 소프트웨어 \ Wow6432Node \ 마이크로 소프트 \ 윈도우 \ CurrentVersion \ 제거 \ {2BBD373C-E9E2-4A64-A17C-FC3F5BE25B7E}] "표시 이름"= "OSSEC HIDS" "언어"= DWORD를 : 00000409 "버전"= DWORD : 02070000 "WindowsInstaller"= dword : 00000001 "DisplayVersion"= "2.7.0" "Ossec HIDS (2.7.0) 나는 값을 복사하여 붙여 넣었습니다. 나는 초보 프로그래머입니다. – user347258

관련 문제