Rename/Update PowerShell ETW manifest to remove the Windows PowerShell dependency. (#5360)

- Build PowerShell.Core.Instrumentation.dll - Resource-only binary for the ETW resources.
- Create a registration script for registering/unregistering the ETW provider.
This commit is contained in:
Dan Travison 2017-11-09 09:23:00 -08:00 committed by Dongbo Wang
parent b1947313c1
commit 3bfae4f1dd
6 changed files with 207 additions and 5 deletions

View file

@ -257,6 +257,24 @@ cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$
log " Copying $srcPath to $dstPath"
Copy-Item $srcPath $dstPath
}
#
# Build the ETW manifest resource-only binary
#
$location = "$PSScriptRoot\src\PowerShell.Core.Instrumentation"
Set-Location -Path $location
$command = @"
cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$Arch -G "$cmakeGenerator" . "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration"
"@
log " Executing Build Command for PowerShell.Core.Instrumentation: $command"
Start-NativeExecution { Invoke-Expression -Command:$command }
# Copy the binary to the packaging directory
# NOTE: No PDB file; it's a resource-only DLL.
$srcPath = [IO.Path]::Combine($location, $Configuration, 'PowerShell.Core.Instrumentation.dll')
Copy-Item -Path $srcPath -Destination $dstPath
} finally {
Pop-Location
}
@ -600,7 +618,7 @@ function New-PSOptions {
[string]$Output,
[switch]$SMAOnly,
[switch]$PSModuleRestore
)

View file

@ -0,0 +1,75 @@
cmake_minimum_required(VERSION 3.5)
#
# Builds PowerShell.Core.Instrumentation.dll resource-only DLL containing ETW event resources
#
# The fully qualified path to the event manifest
SET(EVENTS_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/PowerShell.Core.Instrumentation.man")
# User mode manifest resource-only dll
function(add_manifest_binary)
add_definitions(-D_DLL=1)
add_library(${ARGV})
# NOTE: EVENTS_MANIFEST must be the fully qualified path to the manifest
SET(MC_MANIFEST_FULLNAME ${EVENTS_MANIFEST})
# get the ETW manifest's filename without the directory or extension
get_filename_component(MC_MANIFEST_BASENAME ${EVENTS_MANIFEST} NAME_WE)
SET(MC_COMMAND "mc.exe")
SET(GeneratedManifestFiles)
# The target directory for generated managed files
SET (MC_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}")
# include the generated directory in the include path
include_directories("${MC_GENERATED_DIR}")
SET (MC_GENERATED_FILES
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}TEMP.BIN
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}_MSG00001.BIN
)
SET(MC_COMMAND "mc.exe -h ${MC_GENERATED_DIR} -r ${MC_GENERATED_DIR} ${MC_MANIFEST_FULLNAME}")
add_custom_command(
COMMENT "Generating native event manifest files for ${EVENTS_MANIFEST}"
OUTPUT ${MC_GENERATED_FILES}
DEPENDS ${MC_MANIFEST_FULLNAME}
COMMAND cmd.exe /c ${MC_COMMAND}
WORKING_DIRECTORY ${MC_GENERATED_DIR}
VERBATIM
)
list (APPEND GeneratedManifestFiles ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc)
set_source_files_properties(${GeneratedManifestFiles} PROPERTIES GENERATED TRUE)
add_custom_target(GeneratedManifestFiles DEPENDS ${GeneratedManifestFiles})
# for a resource only dll, cmake can report an error
# if there is no linker language set.
# CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
# Missing variable is: CMAKE_RC_CREATE_SHARED_LIBRARY
get_property(isSet TARGET ${ARGV0} PROPERTY LINKER_LANGUAGE SET)
if (NOT ${isSet})
set_target_properties(${ARGV0} PROPERTIES LINKER_LANGUAGE "CXX")
endif()
set_target_properties(${ARGV0} PROPERTIES LINK_FLAGS "/NODEFAULTLIB /NOENTRY")
if (BUILD_ONECORE)
set_target_properties(${ARGV0} PROPERTIES COMPILE_DEFINITIONS "CORECLR")
endif (BUILD_ONECORE)
# ensure the target is dependent on the generated files.
add_dependencies(${ARGV0} GeneratedManifestFiles)
endfunction()
file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/version.rc)
add_manifest_binary(PowerShell.Core.Instrumentation SHARED ${SOURCES})

View file

@ -12,7 +12,7 @@
<assemblyIdentity
buildType="$(build.buildType)"
language="neutral"
name="PowerShellCore-Instrumentation"
name="PowerShell.Core.Instrumentation"
processorArchitecture="msil"
publicKeyToken="$(build.WindowsPublicKeyToken)"
version="$(build.version)"
@ -31,9 +31,9 @@
first uninstalled and then installed again (using wevtutil)-->
<provider
guid="{f90714a8-5509-434a-bf6d-b1624c8a19a2}"
messageFileName="System.Management.Automation.dll"
messageFileName="PowerShell.Core.Instrumentation.dll"
name="PowerShellCore"
resourceFileName="System.Management.Automation.dll"
resourceFileName="PowerShell.Core.Instrumentation.dll"
symbol="PS_PROVIDER"
>
<!--The following section defines the events which can be written

View file

@ -0,0 +1,94 @@
<#
.Synopsis
Registers or unregisters the PowerShell ETW manifest
.Parameter Path
The fully qualified path to the PowerShell.Core.Instrumentation.man manifest file.
The default value is the location of this script.
.Parameter Unregister
Specify to unregister the manifest.
.Notes
The PowerShell.Core.Instrumentation.man and PowerShell.Core.Instrumentation.dll files are
expected to be at the location specified by the Path parameter.
When registered, PowerShell.Core.Instrumentation.dll is locked to prevent deleting or changing.
To update the binary, first unregister the manifest using the -Unregister switch.
#>
[CmdletBinding()]
param
(
[ValidateNotNullOrEmpty()]
[string] $Path = $PSScriptRoot,
[switch] $Unregister
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Start-NativeExecution([scriptblock]$sb, [switch]$IgnoreExitcode)
{
$backupEAP = $script:ErrorActionPreference
$script:ErrorActionPreference = "Continue"
try
{
& $sb
# note, if $sb doesn't have a native invocation, $LASTEXITCODE will
# point to the obsolete value
if ($LASTEXITCODE -ne 0 -and -not $IgnoreExitcode)
{
throw "Execution of {$sb} failed with exit code $LASTEXITCODE"
}
}
finally
{
$script:ErrorActionPreference = $backupEAP
}
}
function Test-Elevated
{
[CmdletBinding()]
[OutputType([bool])]
Param()
# if the current Powershell session was called with administrator privileges,
# the Administrator Group's well-known SID will show up in the Groups for the current identity.
# Note that the SID won't show up unless the process is elevated.
return (([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -contains "S-1-5-32-544")
}
$IsWindowsOs = $PSHOME.EndsWith('\WindowsPowerShell\v1.0', [System.StringComparison]::OrdinalIgnoreCase) -or $IsWindows
if (-not $IsWindowsOs)
{
throw 'This script must be run on Windows.'
}
if (-not (Test-Elevated))
{
throw 'This script must be run from an elevated process.'
}
$manifest = Get-Item -Path (Join-Path -Path $Path -ChildPath 'PowerShell.Core.Instrumentation.man')
$binary = Get-Item -Path (Join-Path -Path $Path -ChildPath 'PowerShell.Core.Instrumentation.dll')
$files = @($manifest, $binary)
foreach ($file in $files)
{
if (-not (Test-Path -Path $file))
{
throw "Could not find $($file.Name) at $Path"
}
}
[string] $command = "wevtutil um {0}" -f $manifest.FullName
# Unregister if present. Avoids warnings when registering the manifest
# and it is already registered.
Write-Verbose "unregister the manifest, if present: $command"
Start-NativeExecution {Invoke-Expression $command} $true
if (-not $Unregister)
{
$command = "wevtutil.exe im {0} /rf:{1} /mf:{1}" -f $manifest.FullName, $binary.FullName
Write-Verbose -Message "Register the manifest: $command"
Start-NativeExecution { Invoke-Expression $command }
}

View file

@ -0,0 +1,15 @@
//
// Copyright (C) Microsoft. All rights reserved.
//
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DLL
#define VER_FILESUBTYPE VFT2_UNKNOWN
#define VER_FILEDESCRIPTION_STR "PowerShellCore"
#define VER_INTERNALNAME_STR "PowerShell.Core.Instrumentation.dll"
#define VER_ORIGINALFILENAME_STR "PowerShell.Core.Instrumentation.dll"
#include "common.ver"
#include "PowerShell.Core.Instrumentation.rc"

View file

@ -19,7 +19,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="..\..\license_thirdparty_proprietary.txt;..\..\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY;..\powershell-native\Install-PowerShellRemoting.ps1">
<Content Include="..\..\license_thirdparty_proprietary.txt;..\..\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY;..\powershell-native\Install-PowerShellRemoting.ps1;..\PowerShell.Core.Instrumentation\PowerShell.Core.Instrumentation.man;..\PowerShell.Core.Instrumentation\RegisterManifest.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>