-
Notifications
You must be signed in to change notification settings - Fork 341
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from microsoft/main
2021 01 28 Release
- Loading branch information
Showing
17 changed files
with
2,602 additions
and
209,168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
$tagFileBytes = Get-Content "$PSScriptRoot\tags2016.txt" -AsByteStream -Raw | ||
|
||
$htmlFileBytes = Get-Content "$PSScriptRoot\ui.html" -AsByteStream -Raw | ||
|
||
$tagFileContent = [System.Text.Encoding]::UTF8.GetString($tagFileBytes) | ||
|
||
$htmlFileContent = [System.Text.Encoding]::UTF8.GetString($htmlFileBytes) | ||
|
||
$uri = "http://localhost:5002/" | ||
|
||
$outputPath = Join-Path $PSScriptRoot "EnabledTraces.config" | ||
|
||
function GetTagsFromFile($file) { | ||
$tags = $file | ForEach-Object { | ||
if ($_ -match "(^TraceLevels|^InMemoryTracing|^FilteredTracing)" -or $_.Length -lt 1) { | ||
# Skip these lines | ||
} else { | ||
[PSCustomObject]@{ | ||
name = $_.Substring(0, $_.IndexOf(':')) | ||
isSelected = $false | ||
tags = @($_.Substring($_.IndexOf(':') + 1).Split(',') | Sort-Object | ForEach-Object { | ||
[PSCustomObject]@{ | ||
name = $_ | ||
isSelected = $false | ||
} | ||
}) | ||
} | ||
} | ||
} | ||
|
||
return $tags | ||
} | ||
|
||
$extraTags = GetTagsFromFile $tagFileContent.Split([System.Environment]::NewLine) | ||
|
||
$alreadySelectedTags = $null | ||
|
||
if (Test-Path $outputPath) { | ||
$alreadySelectedTags = GetTagsFromFile $outputPath | ||
} | ||
|
||
if ($null -ne $alreadySelectedTags) { | ||
foreach ($category in $alreadySelectedTags) { | ||
$selectedTags = $category.tags | ForEach-Object { $_.name } | ||
$categoryToUpdate = $extraTags | Where-Object { $_.name -eq $category.name } | ||
$categoryToUpdate.tags | ForEach-Object { | ||
if ($selectedTags.Contains($_.name)) { | ||
$_.isSelected = $true | ||
} | ||
} | ||
} | ||
} | ||
|
||
$extraTags = ConvertTo-Json $extraTags -Depth 3 | ||
|
||
$httpListener = New-Object System.Net.HttpListener | ||
$httpListener.Prefixes.Add($uri) | ||
$httpListener.Start() | ||
|
||
& explorer.exe $uri | ||
|
||
try { | ||
while ($httpListener.IsListening) { | ||
$task = $httpListener.GetContextAsync() | ||
while (-not $task.AsyncWaitHandle.WaitOne(100)) { | ||
Start-Sleep -Milliseconds 100 | ||
} | ||
|
||
$context = $task.GetAwaiter().GetResult() | ||
|
||
if ($context.Request.HttpMethod -eq "PUT") { | ||
$context.Response.StatusCode = 200 | ||
$context.Response.Close() | ||
|
||
# The user might have closed the tab, or might have clicked Refresh. | ||
# They both fire the same event. So, wait a moment and see if we get | ||
# another request. If we don't, tab was closed. | ||
$task = $httpListener.GetContextAsync() | ||
if (-not $task.AsyncWaitHandle.WaitOne(1000)) { | ||
Write-Host "Browser tab was closed without saving changes." | ||
break | ||
} else { | ||
$context = $task.GetAwaiter().GetResult() | ||
} | ||
} | ||
|
||
if ($context.Request.HttpMethod -eq "GET") { | ||
Write-Host "Showing tag selector UI in the default browser." | ||
$pageContent = $htmlFileContent.Replace("var exchange2016Tags = [];", "var exchange2016Tags = $extraTags;") | ||
$pageContentUTF8 = [System.Text.Encoding]::UTF8.GetBytes($pageContent) | ||
$context.Response.StatusCode = 200 | ||
$context.Response.OutputStream.Write($pageContentUTF8, 0, $pageContentUTF8.Length) | ||
$context.Response.Close() | ||
} elseif ($context.Request.HttpMethod -eq "POST") { | ||
$reader = New-Object System.IO.StreamReader($context.Request.InputStream, "UTF8") | ||
$body = $reader.ReadToEnd() | ||
$context.Response.StatusCode = 200 | ||
$context.Response.Close() | ||
$tagInfo = ConvertFrom-Json $body | ||
$selectedTags = @() | ||
foreach ($category in $tagInfo) { | ||
$selectedTagsForThisCategory = $category.tags | Where-Object { $_.isSelected } | ||
if ($null -ne $selectedTagsForThisCategory) { | ||
$tagString = [string]::Join(',', ($selectedTagsForThisCategory | ForEach-Object { $_.name })) | ||
$selectedTags += $category.name + ":" + $tagString | ||
} | ||
} | ||
|
||
$linesToSave = @() | ||
$linesToSave += "TraceLevels:Debug,Warning,Error,Fatal,Info,Performance,Function,Pfd" | ||
|
||
Write-Host | ||
Write-Host "Selected tags:" | ||
foreach ($line in $selectedTags) { | ||
Write-Host $line | ||
$linesToSave += $line | ||
} | ||
|
||
$linesToSave += "FilteredTracing:No" | ||
$linesToSave += "InMemoryTracing:No" | ||
|
||
Write-Host | ||
|
||
$outputPath = Join-Path $PSScriptRoot "EnabledTraces.config" | ||
|
||
Write-Host "Saving" $outputPath | ||
|
||
[IO.File]::WriteAllLines($outputPath, $linesToSave) | ||
|
||
break | ||
} | ||
} | ||
} finally { | ||
$httpListener.Close() | ||
} | ||
|
||
if (Test-Path $outputPath) { | ||
Write-Host "The trace can be created, started, and stopped from the command line. Note that" | ||
Write-Host "the `"logman create`" commands should be run from CMD, not PowerShell." | ||
Write-Host | ||
Write-Host "To create a data collector which is non-circular and stops at 1 GB:" | ||
Write-Host | ||
Write-Host "logman create trace ExchangeDebugTraces -p {79bb49e6-2a2c-46e4-9167-fa122525d540} -o c:\tracing\trace.etl -ow -f bin -max 1024" -ForegroundColor Green | ||
Write-Host | ||
Write-Host "To create a data collector which is circular and stops at 2 GB:" | ||
Write-Host | ||
Write-Host "logman create trace ExchangeDebugTraces -p {79bb49e6-2a2c-46e4-9167-fa122525d540} -o c:\tracing\trace.etl -ow -f bincirc -max 2048" -ForegroundColor Green | ||
Write-Host | ||
Write-Host "To start the trace:" | ||
Write-Host | ||
Write-Host "logman start ExchangeDebugTraces" -ForegroundColor Green | ||
Write-Host | ||
Write-Host "To stop the trace:" | ||
Write-Host | ||
Write-Host "logman stop ExchangeDebugTraces" -ForegroundColor Green | ||
Write-Host | ||
Write-Host "The collector can also be started and stopped from Perfmon." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# ExTRA | ||
|
||
The goal of this script is to replace the ExTRA UI that was included with older versions of Exchange. | ||
The script can be run on any machine where a modern browser (Edge/Chrome/Firefox) is set as the default | ||
browser. It does not need to be run on an Exchange server. It will _not_ work if Internet Explorer | ||
is the default browser. | ||
|
||
## Download | ||
|
||
Get the latest release here: | ||
|
||
https://github.com/microsoft/CSS-Exchange/releases/latest/download/ExTRA.ps1 | ||
|
||
## Usage | ||
|
||
Generally, you will want to run this script on a user workstation and use it to generate the | ||
EnabledTraces.config file. Then, that file can be copied to the Exchange server, and a logman command | ||
can be used to start and stop the ExTRA trace. | ||
|
||
The script can be run directly on a server if desired, but remember that IE cannot be the default | ||
browser in that case. | ||
|
||
To use, download the latest release. Then run the script with no parameters: | ||
|
||
``` | ||
.\ExTRA.ps1 | ||
``` | ||
|
||
The default browser will launch with a tag selection interface. Once the desired tags are selected, | ||
click Save and go back to the PowerShell window. You should see some output indicating that the | ||
EnabledTraces.config file was saved in the folder. That EnabledTraces.config should be placed at | ||
the root of C:\ on the server being traced. | ||
|
||
The output also provides example logman syntax for creating, starting, and stopping the trace. |
Oops, something went wrong.