Форум программистов, компьютерный форум, киберфорум
VBScript/JScript/WSH/WMI/HTA
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 16.11.2016
Сообщений: 18
1
VBS

Модифицировать скрипт так, чтобы вывод результатов его работы был в кодировке Win-1251

16.11.2016, 17:04. Показов 2387. Ответов 4

Author24 — интернет-сервис помощи студентам
Приветствую уважаемый форум и прошу помощи!
Не хватает знаний и навыков в VBS самостоятельно модифицировать скрипт.
Скрипт выполняет парсинг вывода команды dcdiag для мониторинга Nagios.
Задача модифицировать его под вывод из РУССКОЙ версии OC Windows Server 2008 R2.
Беда в том, что даже отладить толком не могу, потому что все MsgBox или wscript.echo выдают кракозяблы (вывод ведь идет в CP866). Была мысль сразу перекодировать вывод в WIN-1251 и потом парсить и даже нашел на форуме функцию от Dragokas, но как ее вписать в скрипт не знаю.


Оригинальный скрипт:
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
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
'Script to check the status of a DOMAIN controller and report to Nagios
'requires DCDIAG.EXE 
'Author: Felipe Ferreira
'Version: 3.0
'
'Mauled over by John Jore, j-o-h-n-a-t-j-o-r-e-d-o-t-n-o 16/11/2010 to work on W2K8, x32
'as well as remove some, eh... un-needed lines of code, general optimization as well as adding command parameter support
'This is where i found the original script, [url]http://felipeferreira.net/?p=315&cpage=1#comments[/url]
'Tested by JJ on W2K8 SP2, x86
'        W2K3 R2 SP2, x64
'Version 3.0-JJ-V0.2
'Todo: Proper error handling
'      Add /help parameter
'      Add support for the two tests which require additional input (dcpromo is one such test)
'Version 3.0-JJ-V0.3
'   Removed some surplus language detection code
'       Including non-working English test on a W2K8 x32 DC
'   Added support for multi-partition checks like 'crossrefvalidation'. Previously the last status result would mask previous failures
'   Incorporated Jonathan Vogt's german and multiline tests
 
 
'Force all variables to be declared before usage
option explicit
 
'Array for name and status (Ugly, but redim only works on last dimension, and can't set initial size if redim 
dim name(), status()
redim preserve name(0)
redim preserve status(0)
redim preserve lock(0)
 
'Debug switch
dim verbose : verbose = 0
 
'Return variables for NAGIOS
const intOK = 0
const intWarning = 1 'Not used. What dcdiag test would be warning instead of critical?
const intCritical = 2
const intUnknown = 3
 
'Lang dependend. Default is english
dim strOK : strOK = "пройдена проверка"
dim strNotOK : strNotOk = "не пройдена проверка"
 
'Call dcdiag and grab relevant output
exec(cmd)
 
'Generate NAGIOS compatible output from dcdiag
printout()
 
'call dcdiag and parse the output
sub exec(strCmd)
    'Declare variables
    dim objShell : Set objShell = WScript.CreateObject("WScript.Shell")
    dim objExecObject, lineout, tmpline
    lineout = ""
    'Command line options we're using
    pt strCmd
 
    Set objExecObject = objShell.Exec(strCmd)
    'Loop until end of output from dcdiag
    do While not objExecObject.StdOut.AtEndOfStream
        tmpline = lcase(objExecObject.StdOut.ReadLine())
 
        'Check the version of DCDiag being used and change the global 'passed' / 'failed' strings
        call DetectLang(tmpline)
 
                if (instr(tmpline, ".....")) then 
            'testresults start with a couple of dots, reset the lineout buffer
            lineout= tmpline
            'pt "lineout buffer '" & lineout & "'"
        else
            'Else append the next line to the buffer to capture multiline responses
            lineout = lineout + tmpline
            'pt "lineout buffer appended '" & lineout & "'"
        end if
 
        if instr(lineout, lcase(strOK)) then
            'we have a strOK String which means we have reached the end of a result output (maybe on newline)
            call parse(lineout)
            lineout = ""
        end if 
    loop
 
    'Why call this at the end? Is it not pointless as we've looped through the entire output from dcdiag in the above loop?!?
    'call parse(lineout)
end sub
 
 
sub DetectLang(txtp)
 
    'Change from looking for English words if we find the string below:
    if (instr(lcase(txtp), lcase("Verzeichnisserverdiagnose"))) then 'German
                pt "Detected German Language, changing the global test strings to look for"
        strOK = "пройдена проверка"
        strNotOk = "не пройдена проверка"
    end if
 
end sub
 
 
sub parse(txtp)
    'Parse output of dcdiag command and change state of checks
    dim loop1
 
        'Is this really required? Or is it for pretty debug output only?
    txtp = Replace(txtp,chr(10),"") ' Newline
    txtp = Replace(txtp,chr(13),"") ' CR
    txtp = Replace(txtp,chr(9),"")  ' Tab
    do while instr(txtp, "  ")
      txtp = Replace(txtp,"  "," ") ' Some tidy up
    loop
    
    ' We have to test twice because some localized (e.g. German) outputs simply use 'not', or 'nicht' as a prefix instead of 'passed' / 'failed'
    if instr(lcase(txtp), lcase(strOK)) then
        'What are we testing for now?
        pt "Checking :" & txtp & "' as it contains '" & strOK & "'"
        'What services are ok? 'By using instr we don't need to strip down text, remove vbCr, VbLf, or get the hostname
        for loop1 = 0 to Ubound(name)-1
            if (instr(lcase(txtp), lcase(name(loop1)))) AND (lock(loop1) = FALSE) then 
                status(loop1)="OK"
                pt "Set the status for test '" & name(loop1) & "' to '" & status(loop1) & "'"
            end if
        next
    end if
 
    ' if we find the strNotOK string then reset to CRITICAL
    if instr(lcase(txtp), lcase(strNotOK)) then
        'What are we testing for now?
        pt txtp
        for loop1 = 0 to Ubound(name)-1
            if (instr(lcase(txtp), lcase(name(loop1)))) then 
                status(loop1)="CRITICAL"
                'Lock the variable so it can't be reset back to success. Required for multi-partition tests like 'crossrefvalidation'
                lock(loop1)=TRUE
                pt "Reset the status for test '" & name(loop1) & "' to '" & status(loop1) & "' with a lock '" & lock(loop1) & "'"
            end if
        next
    end if
end sub
 
'outputs result for NAGIOS
sub printout()
    dim loop1, msg : msg = ""
 
    for loop1 = 0 to ubound(name)-1
        msg = msg & name(loop1) & ": " & status(loop1) & ". "
    next
 
    'What state are we in? Show and then quit with NAGIOS compatible exit code
    if instr(msg,"CRITICAL") then
        wscript.echo "CRITICAL - " & msg
        wscript.quit(intCritical)
    else
        wscript.echo "OK - " & msg
        wscript.quit(intOK)
    end if
end sub
 
'Print messages to screen for debug purposes
sub pt(msgTxt)
    if verbose then
        wscript.echo msgTXT
    end if
end sub
 
'What tests do we run?
function cmd()
    dim loop1, test, tests
    const intDefaultTests = 6
 
    cmd = "dcdiag " 'Start with this
 
    'If no command line parameters, then go with these defaults
    if Wscript.Arguments.Count = 0 Then
        redim preserve name(intDefaultTests)
        redim preserve status(intDefaultTests)
        redim preserve lock(intDefaultTests)
        'Test name
        name(0) = "services"
        name(1) = "replications"
        name(2) = "advertising"
        name(3) = "fsmocheck"
        name(4) = "ridmanager"
        name(5) = "machineaccount"
 
        'Set default status for each named test
        for loop1 = 0 to (ubound(name)-1)
            status(loop1) = "CRITICAL"
            lock(loop1) = FALSE
            cmd = cmd & "/test:" & name(loop1) & " "
        next
    else
        'User specified which tests to perform.
 
        for loop1 = 0 to wscript.arguments.count - 1
            if (instr(lcase(wscript.Arguments(loop1)), lcase("/test"))) then
            
            'If parameter is wrong, give some hints
            if len(wscript.arguments(loop1)) < 6 then
                wscript.echo "Unknown parameter. Provide name of tests to perform like this:"
                wscript.echo vbTAB & "'cscript //nologo " & Wscript.ScriptName & " /test:advertising,dfsevent'"
                wscript.quit(intUnknown)
            end if
            
            'Strip down the test to individual items
            tests = right(wscript.arguments(loop1), len(wscript.arguments(loop1))-6)
            pt "Tests: '" & tests & "'"
 
            tests = split(tests,",")
            for each test in tests
                cmd = cmd  & " /test:" & test
 
                'Expand the array to make room for one more test
                redim preserve name(ubound(name)+1)
                redim preserve status(ubound(status)+1)
                redim preserve lock(ubound(lock)+1)
 
                'Store name of test and status
                name(Ubound(name)-1) = test
                status(Ubound(status)-1) = "CRITICAL" 'Default status. Change to OK if test is ok
                lock(Ubound(lock)-1) = FALSE 'Don't lock the variable yet.
 
                'pt "Contents: " & name(Ubound(name)-1) & " " & status(Ubound(status)-1)
            next
            end if
        next
    end if
    'We end up with this to test:
    pt "Command to run: " & cmd
end function
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.11.2016, 17:04
Ответы с готовыми решениями:

Вывод текста в кодировке Win-1251 из bat-файла, текст которого в кодировке OEM-866
примем за аксиому утверждение: &quot;bat-скрипт следует создавать в кодировке DOS (OEM-866)&quot; ...пусть...

Модифицировать метод Array.prototype.indexOf () так, чтобы первым его параметром был вектор из нескольких элементов
навскидку реализация видится такой: использовать существующую функциональность метода...

Модифицировать код так, чтобы появилась возможность его запустить
Помоги запустить в консольном предложени в с# бинарный поиск вот этот код: /* Номер первого...

Как данные, полученные в кодировке Win-1251 привести к читаемому виду в QString?
Привет ещё раз! Приходят данные из одной функции по указателю на void*. Формат и длина данных...

4
5986 / 1995 / 323
Регистрация: 10.12.2013
Сообщений: 6,875
17.11.2016, 01:54 2
Boltun177,
а ты не мог бы приложить файл вывода dcdiag ?
0
0 / 0 / 0
Регистрация: 16.11.2016
Сообщений: 18
17.11.2016, 08:04  [ТС] 3
Цитата Сообщение от volodin661 Посмотреть сообщение
а ты не мог бы приложить файл вывода dcdiag ?
Насколько я смог прочитать скрипт, выборка идет по строке в англ. варианте passed/failed
В русском варианте это "пройдена проверка/не пройдена проверка" (или просто "пройдена/не пройдена")

Вот вывод одной из команд, выполняемой в скрипте
Код
C:\Windows\system32>dcdiag /test:replications

Диагностика сервера каталогов

Выполнение начальной настройки:
   Выполняется попытка поиска основного сервера...
   Основной сервер = 1-dc
   * Идентифицирован лес AD.
   Сбор начальных данных завершен.

Выполнение обязательных начальных проверок

   Сервер проверки: Default-First-Site-Name\1-DC
      Запуск проверки: Connectivity
         ......................... 1-DC - пройдена проверка Connectivity

Выполнение основных проверок

   Сервер проверки: Default-First-Site-Name\1-DC
      Запуск проверки: Replications
         ......................... 1-DC - пройдена проверка Replications


   Выполнение проверок разделов на: ForestDnsZones

   Выполнение проверок разделов на: DomainDnsZones

   Выполнение проверок разделов на: Schema

   Выполнение проверок разделов на: Configuration

   Выполнение проверок разделов на: domen

   Выполнение проверок предприятия на: domen.ru

C:\Windows\system32>
0
0 / 0 / 0
Регистрация: 16.11.2016
Сообщений: 18
17.11.2016, 11:04  [ТС] 4
На всякий вкладываю файликом вывод команды
Вложения
Тип файла: txt dcdiag.txt (970 байт, 3 просмотров)
0
Эксперт WindowsАвтор FAQ
17996 / 7697 / 892
Регистрация: 25.12.2011
Сообщений: 11,470
Записей в блоге: 16
20.11.2016, 15:39 5
Цитата Сообщение от Boltun177 Посмотреть сообщение
парсить и даже нашел на форуме функцию от Dragokas, но как ее вписать в скрипт не знаю.
Там работа с файлом. FullName - имя файла. В .Charset -ы подставляются кодировки. "cp866" и "windows-1251".
Для вывода на экран, данные следует грузить не из файла, а методом WriteText (при условии, что в тексте кроме симсолов алфавита и обычных знаков клавиатуры, другие не встречаются), иначе следует использовать метод Write с предварительным преобразованием текста в массив байтов. А после конвертации кодировки, обратно - из массива в строку. А читать обратно через ReadText / Read.

Пример через WriteText / ReadText объекта ADODB.Stream:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
'866 -> 1251
sub recode(sText)
  With CreateObject("ADODB.Stream")
    .Type = 2
    .Mode = 3
    .Charset = "windows-1251"
    .Open
    .WriteText sText
    .Position = 0
    .Charset = "cp866"
    wscript.echo(.ReadText)
    .Close
  End with
end sub
в процедурах
- sub printout()
- sub pt(msgTxt)

используемого вами кода заменить все
Visual Basic
1
wscript.echo ...
на
Visual Basic
1
recode ...
2
20.11.2016, 15:39
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.11.2016, 15:39
Помогаю со студенческими работами здесь

Модифицировать задание из лабораторной работы так, чтобы каждое из полей (TEdit) в незаполненном состоянии, всегда содержало бы “0”
Модифицировать задание из лабораторной работы №11 так, чтобы каждое из полей (TEdit) в...

Записать массив в файл так, чтобы он был равномерно записан на его строках
с клавиатуры или случайным образом заполняется массив.Количество элементов массива-константа N.С...

Как сделать так, чтобы ввод и вывод данных и результатов выполнялся в нестандартном текстовом файле?
Есть определенный код program Lab2; {$APPTYPE CONSOLE} Uses Windows; var i, n, x:...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru