Skip to content

Search administration — crawl diagnostics, popular queries, search

service configuration, and manual suggestions.

Provides search admins with tools to: - Check search service configuration (search center URL, result URL) - View crawl status and unsuccessful URLs - Export popular tenant queries - Export and update manual query suggestions

Permissions

Requires delegated permission Sites.ReadWrite.All for most operations; Sites.FullControl.All for configuration updates.

Reference

View source

from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.search.administration.document_crawl_log import DocumentCrawlLog
from tests.settings import cert_path, cert_thumbprint, client_id, site_url, tenant


def main():
    ctx = ClientContext(site_url).with_client_certificate(
        tenant, client_id=client_id, thumbprint=cert_thumbprint, cert_path=cert_path
    )

    search_svc = ctx.search

    # -- Step 1: query search service configuration --
    center_url = search_svc.search_center_url().execute_query()
    result_url = search_svc.results_page_address().execute_query()

    print("Search service configuration:\n")
    print(f"  Search center URL:   {center_url.value or '(not set)'}")
    print(f"  Results page address: {result_url.value or '(default)'}\n")

    # -- Step 2: export popular tenant queries --
    popular = search_svc.export_popular_tenant_queries(count=10).execute_query()
    if popular and popular.value:
        print(f"Popular tenant queries (top {len(popular.value)}):")
        for i, q in enumerate(popular.value, 1):
            print(f"  {i:2d}. {q.QueryText:45s}  count={q.QueryCount}")
    else:
        print("(No popular tenant query data available)")
    print()

    # -- Step 3: export manual query suggestions --
    suggestions = search_svc.export_manual_suggestions().execute_query()
    if suggestions and suggestions.value:
        always_suggest = suggestions.value.AlwaysSuggest
        total = sum(len(s.Queries) for s in always_suggest)
        print(f"Manual query suggestions ({total}):")
        for s in always_suggest:
            for q in s.Queries:
                print(f"  - {q}")
    else:
        print("(No manual suggestions configured)")
    print()

    # -- Step 4: document crawl log diagnostics --
    try:
        crawl_log = DocumentCrawlLog.create(ctx)
        print("Document crawl log:")
        # Get crawled URLs (first page)
        urls = crawl_log.get_crawled_urls().execute_query()
        if urls and urls.value and len(urls.value.Rows):
            rows = list(urls.value.Rows)
            print(f"  Crawl log entries: {len(rows)}")
            for row in rows[:5]:
                print(f"    URL: {row.Cells.get('url', '?')}")
        else:
            print("  (no crawl log data)")

        # Get unsuccessful crawls
        failed = crawl_log.get_unsuccesful_crawled_urls().execute_query()
        if failed and failed.value and len(failed.value.Rows):
            rows = list(failed.value.Rows)
            print(f"  Unsuccessful URLs: {len(rows)}")
            for row in rows[:5]:
                print(f"    URL: {row.Cells.get('url', '?')}  error: {row.Cells.get('error', '?')}")
    except Exception as e:
        print(f"  (crawl diagnostics not available: {e})")


if __name__ == "__main__":
    main()

← Back to Admin