Загрузка данных
$ErrorActionPreference = "Continue"
# ===== НАСТРОЙКА =====
# Если знаешь ящик, на котором ловишь 0x8004010F — укажи здесь.
# Можно оставить пустым.
$Mailbox = ""
$ReportDir = "C:\Temp"
if (!(Test-Path $ReportDir)) {
New-Item -ItemType Directory -Path $ReportDir -Force | Out-Null
}
$Report = Join-Path $ReportDir ("Exchange-OAB-Diag_{0}.txt" -f (Get-Date -Format "yyyyMMdd_HHmmss"))
Start-Transcript -Path $Report -Force
function Header($Text) {
Write-Host ""
Write-Host "============================================================"
Write-Host $Text
Write-Host "============================================================"
}
Header "1. BASIC INFORMATION"
Write-Host "Computer:"
$env:COMPUTERNAME
Write-Host "`nDate:"
Get-Date
Write-Host "`nExchange servers:"
Get-ExchangeServer |
Format-Table Name,ServerRole,Edition,AdminDisplayVersion -AutoSize
Header "2. OFFLINE ADDRESS BOOKS"
try {
Get-OfflineAddressBook |
Format-List Name,
Identity,
AddressLists,
GeneratingMailbox,
GlobalWebDistributionEnabled,
VirtualDirectories,
IsDefault,
WhenChanged
}
catch {
Write-Host "ERROR Get-OfflineAddressBook:"
Write-Host $_
}
Header "3. OAB GENERATION MAILBOX"
try {
Get-Mailbox -Arbitration -ResultSize Unlimited |
Where-Object {
$_.PersistedCapabilities -match "OAB"
} |
Format-List Name,
Alias,
DisplayName,
ServerName,
Database,
PersistedCapabilities
}
catch {
Write-Host "ERROR OAB arbitration mailbox:"
Write-Host $_
}
Header "4. OAB VIRTUAL DIRECTORIES"
try {
Get-OabVirtualDirectory |
Format-List Identity,
Server,
InternalUrl,
ExternalUrl,
RequireSSL,
BasicAuthentication,
WindowsAuthentication
}
catch {
Write-Host "ERROR Get-OabVirtualDirectory:"
Write-Host $_
}
Header "5. AUTODISCOVER SCP"
if (Get-Command Get-ClientAccessService -ErrorAction SilentlyContinue) {
Get-ClientAccessService |
Format-List Name,
AutoDiscoverServiceInternalUri
}
elseif (Get-Command Get-ClientAccessServer -ErrorAction SilentlyContinue) {
Get-ClientAccessServer |
Format-List Name,
AutoDiscoverServiceInternalUri
}
else {
Write-Host "Get-ClientAccessService/Get-ClientAccessServer unavailable."
}
Header "6. MAILBOX DATABASE -> OAB MAPPING"
try {
Get-MailboxDatabase -Status |
Format-Table Name,
Server,
Mounted,
OfflineAddressBook -AutoSize
}
catch {
Write-Host "ERROR Get-MailboxDatabase:"
Write-Host $_
}
Header "7. ADDRESS BOOK POLICIES"
if (Get-Command Get-AddressBookPolicy -ErrorAction SilentlyContinue) {
try {
Get-AddressBookPolicy |
Format-List Name,
AddressLists,
GlobalAddressList,
OfflineAddressBook,
RoomList
}
catch {
Write-Host $_
}
}
else {
Write-Host "Get-AddressBookPolicy unavailable."
}
Header "8. MAILBOX-SPECIFIC CHECK"
if ([string]::IsNullOrWhiteSpace($Mailbox)) {
Write-Host "Mailbox variable is empty - mailbox-specific test skipped."
Write-Host 'To test a user, set at the start: $Mailbox = "user@domain.ru"'
}
else {
try {
$Mbx = Get-Mailbox $Mailbox -ErrorAction Stop
$Mbx |
Format-List Name,
PrimarySmtpAddress,
ServerName,
Database,
AddressBookPolicy,
RecipientTypeDetails
Write-Host "`nMailbox database configuration:"
Get-MailboxDatabase $Mbx.Database |
Format-List Name,
Server,
OfflineAddressBook
if ($Mbx.AddressBookPolicy) {
Write-Host "`nMailbox Address Book Policy:"
Get-AddressBookPolicy $Mbx.AddressBookPolicy |
Format-List Name,
GlobalAddressList,
OfflineAddressBook,
AddressLists,
RoomList
}
}
catch {
Write-Host "ERROR mailbox check:"
Write-Host $_
}
}
Header "9. IIS OAB APPLICATION"
try {
Import-Module WebAdministration -ErrorAction Stop
Write-Host "`nOAB applications:"
Get-WebApplication |
Where-Object {
$_.Path -match "OAB"
} |
Format-Table Path,ApplicationPool,PhysicalPath -AutoSize
Write-Host "`nMSExchangeOABAppPool:"
if (Test-Path "IIS:\AppPools\MSExchangeOABAppPool") {
Get-WebAppPoolState "MSExchangeOABAppPool"
Get-Item "IIS:\AppPools\MSExchangeOABAppPool" |
Format-List Name,
State,
managedRuntimeVersion,
startMode
}
else {
Write-Host "MSExchangeOABAppPool not found on this server."
}
}
catch {
Write-Host "IIS check unavailable/error:"
Write-Host $_
}
Header "10. LOCAL OAB FILES"
$ExchangePath = $env:ExchangeInstallPath
if ($ExchangePath) {
$OABPath = Join-Path $ExchangePath "ClientAccess\OAB"
Write-Host "Expected path:"
Write-Host $OABPath
if (Test-Path $OABPath) {
Write-Host "`nNewest OAB files:"
Get-ChildItem $OABPath -Recurse -File -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending |
Select-Object -First 30 FullName,
Length,
LastWriteTime |
Format-Table -AutoSize
}
else {
Write-Host "OAB directory does not exist on this server."
}
}
else {
Write-Host "ExchangeInstallPath environment variable not found."
}
Header "11. OAB URL DNS / HTTP CHECK"
try {
$OabUrls = Get-OabVirtualDirectory |
ForEach-Object {
$_.InternalUrl
$_.ExternalUrl
} |
Where-Object { $_ } |
Select-Object -Unique
foreach ($Url in $OabUrls) {
Write-Host ""
Write-Host "----- $Url -----"
try {
$Uri = [Uri]$Url
Write-Host "Host: $($Uri.Host)"
Write-Host "`nDNS:"
Resolve-DnsName $Uri.Host -ErrorAction Stop |
Format-Table Name,Type,IPAddress -AutoSize
}
catch {
Write-Host "DNS ERROR:"
Write-Host $_.Exception.Message
}
try {
Write-Host "`nHTTP test:"
$Response = Invoke-WebRequest `
-Uri $Url `
-Method Head `
-UseBasicParsing `
-MaximumRedirection 0 `
-TimeoutSec 10 `
-ErrorAction Stop
Write-Host "HTTP status: $($Response.StatusCode)"
}
catch {
if ($_.Exception.Response) {
try {
$Status = [int]$_.Exception.Response.StatusCode
Write-Host "HTTP status: $Status"
}
catch {
Write-Host $_.Exception.Message
}
}
else {
Write-Host "HTTP ERROR:"
Write-Host $_.Exception.Message
}
}
}
}
catch {
Write-Host "OAB URL test error:"
Write-Host $_
}
Header "12. EXCHANGE HEALTH - OAB / AUTODISCOVER"
if (Get-Command Get-ServerHealth -ErrorAction SilentlyContinue) {
try {
Get-ExchangeServer |
ForEach-Object {
$Server = $_.Name
Write-Host ""
Write-Host "SERVER: $Server"
Get-ServerHealth -Identity $Server -ErrorAction SilentlyContinue |
Where-Object {
$_.HealthSetName -match "OAB|Autodiscover" -or
$_.Name -match "OAB|Autodiscover"
} |
Format-Table Server,
HealthSetName,
Name,
AlertValue,
State -AutoSize
}
}
catch {
Write-Host "Health check error:"
Write-Host $_
}
}
else {
Write-Host "Get-ServerHealth unavailable."
}
Header "13. RECENT EXCHANGE OAB / AUTODISCOVER ERRORS"
try {
$Start = (Get-Date).AddDays(-3)
Get-WinEvent `
-FilterHashtable @{
LogName = "Application"
StartTime = $Start
Level = 2,3
} `
-ErrorAction SilentlyContinue |
Where-Object {
$_.ProviderName -match "Exchange" -and
$_.Message -match "OAB|Offline Address Book|Autodiscover"
} |
Select-Object -First 50 `
TimeCreated,
ProviderName,
Id,
LevelDisplayName,
Message |
Format-List
}
catch {
Write-Host "Event log query error:"
Write-Host $_
}
Header "14. IMPORTANT EXCHANGE SERVICES"
Get-Service |
Where-Object {
$_.Name -match "^MSExchange"
} |
Sort-Object Name |
Format-Table Status,
StartType,
Name,
DisplayName -AutoSize
Header "DIAGNOSTICS COMPLETE"
Write-Host ""
Write-Host "REPORT SAVED TO:"
Write-Host $Report
Write-Host ""
Stop-Transcript