Как получить полезную информацию из счетчиков производительности поискового индексатора?

484
Michał Masny

Я пытался найти способ получить информацию о прогрессе индексирования программным способом (сколько файлов нужно пройти или «индексирование завершено»). Я наткнулся на класс Win32_PerfFormattedData_WSearchIdxPi_SearchIndexer и был удивлен количеством показанных мне нулей, особенно нуля рядом с «IndexSize».

enter image description here

Параметры индексирования показывают 5055 элементов, проиндексированных, поэтому, на мой взгляд, размер индекса должен быть ненулевым.

enter image description here

Какую информацию представляют эти нули? Я не смотрю на правильный класс? Если я, я должен сделать что-то, чтобы получить другие номера?

Это на Windows 8.1, но компьютеры, на которых я действительно хотел бы делать подобные вещи, - это системы Windows 7 и Windows 10.

Я сейчас работаю на компьютере с Windows 10, и это выглядит немного иначе. ActiveConnections показывает 2 вместо 0 здесь. Я также заметил, что на обоих компьютерах некоторые свойства, отсутствующие в FormattedData, Frequency_Sys100NS, показаны в RawData:

Необработанные данные:

PS C:\WINDOWS\system32> gwmi Win32_PerfRawData_WSearchIdxPi_SearchIndexer   __GENUS : 2 __CLASS : Win32_PerfRawData_WSearchIdxPi_SearchIndexer __SUPERCLASS : Win32_PerfRawData __DYNASTY : CIM_StatisticalInformation __RELPATH : Win32_PerfRawData_WSearchIdxPi_SearchIndexer.Name="SystemIndex" __PROPERTY_COUNT : 72 __DERIVATION :  __SERVER : WRW-MXM0121 __NAMESPACE : root\cimv2 __PATH : \\WRW-MXM0121\root\cimv2:Win32_PerfRawData_WSearchIdxPi_SearchIndexer.Name="SystemIndex" ActiveConnections : 2 Caption :  CleanWidSets : 0 Description :  DirtyWidSets : 0 DocumentsFiltered : 0 Frequency_Object : 0 Frequency_PerfTime : 0 Frequency_Sys100NS : 10000000 IndexSize : 0 L0IndexesWordlists : 1 L0MergeFlushCount : 0 L0MergeFlushSpeedAverage : 0 L0MergeFlushSpeedLast : 0 L0MergesflushesNow : 0 L1MergeCount : 0 L1MergesNow : 0 L1MergeSpeedaverage : 0 L1MergeSpeedlast : 0 L2MergeCount : 0 L2MergesNow : 0 L2MergeSpeedaverage : 0 L2MergeSpeedlast : 0 L3MergeCount : 0 L3MergesNow : 0 L3MergeSpeedaverage : 0 L3MergeSpeedlast : 0 L4MergeCount : 0 L4MergesNow : 0 L4MergeSpeedaverage : 0 L4MergeSpeedlast : 0 L5MergeCount : 0 L5MergesNow : 0 L5MergeSpeedaverage : 0 L5MergeSpeedlast : 0 L6MergeCount : 0 L6MergesNow : 0 L6MergeSpeedaverage : 0 L6MergeSpeedlast : 0 L7MergeCount : 0 L7MergesNow : 0 L7MergeSpeedaverage : 0 L7MergeSpeedlast : 0 L8MergeCount : 0 L8MergesNow : 0 L8MergeSpeedaverage : 0 L8MergeSpeedlast : 0 MasterIndexLevel : 0 MasterMergeProgress : 0 MasterMergesNow : 0 MasterMergestoDate : 0 Name : SystemIndex PersistentIndexes : 4 PersistentIndexesL1 : 0 PersistentIndexesL2 : 0 PersistentIndexesL3 : 0 PersistentIndexesL4 : 0 PersistentIndexesL5 : 0 PersistentIndexesL6 : 0 PersistentIndexesL7 : 0 PersistentIndexesL8 : 0 Queries : 520 QueriesFailed : 1 QueriesSucceeded : 519 ShadowMergeLevels : 0 ShadowMergeLevelsThreshold : 0 Timestamp_Object : 0 Timestamp_PerfTime : 0 Timestamp_Sys100NS : 131122139817760000 UniqueKeys : 0 WorkItemsCreated : 0 WorkItemsDeleted : 0 PSComputerName : WRW-MXM0121 

FormattedData:

PS C:\WINDOWS\system32> gwmi Win32_PerfRawData_WSearchIdxPi_SearchIndexer __GENUS : 2 __CLASS : Win32_PerfFormattedData_WSearchIdxPi_SearchIndexer __SUPERCLASS : Win32_PerfFormattedData __DYNASTY : CIM_StatisticalInformation __RELPATH : Win32_PerfFormattedData_WSearchIdxPi_SearchIndexer.Name="SystemIndex" __PROPERTY_COUNT : 72 __DERIVATION :  __SERVER : WRW-MXM0121 __NAMESPACE : root\cimv2 __PATH : \\WRW-MXM0121\root\cimv2:Win32_PerfFormattedData_WSearchIdxPi_SearchIndexer.Name="SystemIn dex" ActiveConnections : 2 Caption :  CleanWidSets : 0 Description :  DirtyWidSets : 0 DocumentsFiltered : 0 Frequency_Object :  Frequency_PerfTime :  Frequency_Sys100NS :  IndexSize : 0 L0IndexesWordlists : 1 L0MergeFlushCount : 0 L0MergeFlushSpeedAverage : 0 L0MergeFlushSpeedLast : 0 L0MergesflushesNow : 0 L1MergeCount : 0 L1MergesNow : 0 L1MergeSpeedaverage : 0 L1MergeSpeedlast : 0 L2MergeCount : 0 L2MergesNow : 0 L2MergeSpeedaverage : 0 L2MergeSpeedlast : 0 L3MergeCount : 0 L3MergesNow : 0 L3MergeSpeedaverage : 0 L3MergeSpeedlast : 0 L4MergeCount : 0 L4MergesNow : 0 L4MergeSpeedaverage : 0 L4MergeSpeedlast : 0 L5MergeCount : 0 L5MergesNow : 0 L5MergeSpeedaverage : 0 L5MergeSpeedlast : 0 L6MergeCount : 0 L6MergesNow : 0 L6MergeSpeedaverage : 0 L6MergeSpeedlast : 0 L7MergeCount : 0 L7MergesNow : 0 L7MergeSpeedaverage : 0 L7MergeSpeedlast : 0 L8MergeCount : 0 L8MergesNow : 0 L8MergeSpeedaverage : 0 L8MergeSpeedlast : 0 MasterIndexLevel : 0 MasterMergeProgress : 0 MasterMergesNow : 0 MasterMergestoDate : 0 Name : SystemIndex PersistentIndexes : 4 PersistentIndexesL1 : 0 PersistentIndexesL2 : 0 PersistentIndexesL3 : 0 PersistentIndexesL4 : 0 PersistentIndexesL5 : 0 PersistentIndexesL6 : 0 PersistentIndexesL7 : 0 PersistentIndexesL8 : 0 Queries : 523 QueriesFailed : 1 QueriesSucceeded : 522 ShadowMergeLevels : 0 ShadowMergeLevelsThreshold : 0 Timestamp_Object :  Timestamp_PerfTime :  Timestamp_Sys100NS :  UniqueKeys : 0 WorkItemsCreated : 0 WorkItemsDeleted : 0 PSComputerName : WRW-MXM0121 

И вот пример того, как счетчики производительности Search Indexer выглядят в mmc.exe (это снова на компьютере с Windows 10, но на компьютере с Windows 8.1 это выглядит так же). Это просто вертикальная линия, движущаяся по экрану - в данном случае счетчик имеет размер индекса.

enter image description here

И скриншот с Get-Counter от Powershell в действии:

enter image description here

4

1 ответ на вопрос

2
Ben N

Этот класс WMI каким-то образом нарушен. К счастью, есть обходной путь, хотя он требует немного больше работы. Вам нужно будет загрузить Windows Search 3 SDK . Это просто самораспаковывающийся ZIP, и вы можете помещать файлы куда угодно. Мы заинтересованы только в одном, Microsoft.Search.Interop.dllв папке Managed. Загрузите эту DLL в PowerShell:

Add-Type -Path "Microsoft.Search.Interop.dll" 

Тогда вам нужен объект менеджера поиска . Если вы хотите получить тот для локальной машины, это просто так:

$manager = New-Object Microsoft.Search.Interop.CSearchManagerClass 

Если вы хотите получить доступ к удаленной машине, пришло время для объезда.


Нам понадобится GUID класса COM, который я где-то извлек из заголовка C:

$guid = New-Object guid "" 

И мы создадим тип COM таким образом, что Windows сделает RPC за нас:

$managerType = [Type]::GetTypeFromCLSID($guid, $targetMachine, $true) 

Определить тип:

$comManager = [Activator]::CreateInstance($managerType) 

Превратите этот COM-объект обратно в обычный .NET-объект:

$manager = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($comManager, [Microsoft.Search.Interop.CSearchManagerClass]) 

Обход завершен. Теперь этот объект будет ссылаться на менеджер поиска целевой машины.


Затем получите объект каталога для основного каталога:

$cat = $manager.GetCatalog("SystemIndex") 

GetCatalogStatusФункция сообщает вам, будь то в настоящее время индексации, но эта функция использует «выход» параметры, поэтому мы должны передать ссылки:

$indexStatus = 0 $indexPauseReason = 0 $cat.GetCatalogStatus([ref]$indexStatus, [ref]$indexPauseReason) 

Эти две переменные теперь содержат неопределенно читаемый статус, если вы заставляете их быть строками. [string]$indexStatusВ настоящее время производит CATALOG_STATUS_PAUSEDдля меня. Если индексатор приостановлен, эта вторая переменная является причиной, по которой он не работает.

Получить количество проиндексированных элементов довольно просто:

$cat.NumberOfItems() 

Предположительно, Windows выполняет индексацию, когда для индексирования больше ничего не осталось, поэтому мы будем использовать NumberOfItemsToIndexфункцию, опять же со ссылками:

$incrementalCount = 0 $notificationQueue = 0 $highPriQueue = 0 $cat.NumberOfItemsToIndex([ref]$incrementalCount, [ref]$notificationQueue, [ref]$highPriQueue) 

Если все три из этих переменных получаются нулевыми, то индексация завершена.

Все эти функции дают ожидаемые / правильные результаты в Windows 8.1, в то время как WMI делает для меня то же самое, что и для вас.

Спасибо за этот ответ. Я фактически задал [отдельный вопрос] (http://stackoverflow.com/questions/38193717/cant-query-systemindex-on-my-own-machine-when-i-specify-the-machine-name) об этом Переполнение стека. Проблема в том, что он не может подключиться к удаленному каталогу. (+1 конечно) Michał Masny 7 лет назад 0
Ах, я не знал, что это требование. Один из способов сделать это - заключить весь скрипт в [Invoke-Command`] (https://technet.microsoft.com/en-us/library/dd347578.aspx): `Invoke-Command -ComputerName server1 , server2 {} `. Все, что вы вернете из этого блока скрипта, появится на локальном компьютере. К сожалению, DLL нужно будет разместить на сетевом ресурсе или иным образом сделать доступным для всех целей. Ben N 7 лет назад 0
Это хорошая идея, спасибо. Я протестировал программу из другого вопроса с PsExec тоже, и она также работает нормально. Было бы неплохо иметь что-то, что не было бы взломом :) Вы говорите, что нет способа использовать эту DLL (или какую-то другую) для подключения к удаленному компьютеру? Если бы я знал, как реализован этот метод GetCatalog, возможно, я мог бы просто как-то его расширить, но я также не знаю, как это выяснить, и я не программист на C ++ ... Я возьму награду за другой вопрос, на случай, если тебе хочется ответить. Michał Masny 7 лет назад 0
@ymar К сожалению, я не могу найти ни одного экземпляра в Интернете, в котором люди успешно использовали бы этот интерфейс (в C ++ или .NET) для работы с удаленной машиной. Ben N 7 лет назад 0
@ymar Я обновил свой ответ объездом для удаленных машин. Почти наверняка потребуется, чтобы оба компьютера были частью одного домена и чтобы скрипт запускался от имени администратора. Это работает для меня, когда я указываю имя моего собственного компьютера в качестве цели, но у меня нет домена для тестирования здесь. Ben N 7 лет назад 0