Merge branch 'master' into UnitTest_Temp

This commit is contained in:
Ting Liu [Wicresoft] committed 2016-04-06 16:27:44 +08:00
commit 9733f5e8e7
157 files changed
+18618 -707

No files matched your search

+10 -2
View File
@@ -1,6 +1,14 @@
bin/ bin/
binFull/
build/
obj/ obj/
project.lock.json project.lock.json
*-tests.xml *-tests.xml
# dotnet cli install.ps1 script
install.ps1
# VS auto-generated solution files for project.json solutions
*.xproj
*.xproj.user
# We copy powershell.exe as a content in host dotnet cli projects
*.exe
+6 -5
View File
@@ -1,6 +1,3 @@
[submodule "src/libpsl-native"]
path = src/libpsl-native
url = https://github.com/PowerShell/psl-native.git
[submodule "src/omi"] [submodule "src/omi"]
path = src/omi path = src/omi
url = https://github.com/Microsoft/omi.git url = https://github.com/Microsoft/omi.git
@@ -11,8 +8,12 @@
[submodule "src/windows-build"] [submodule "src/windows-build"]
path = src/windows-build path = src/windows-build
url = https://github.com/PowerShell/psl-windows-build.git url = https://github.com/PowerShell/psl-windows-build.git
[submodule "src/Microsoft.PowerShell.Linux.Host/Modules/Pester"] [submodule "src/Modules/Pester"]
path = src/Microsoft.PowerShell.Linux.Host/Modules/Pester path = src/Modules/Pester
url = https://github.com/PowerShell/psl-pester.git url = https://github.com/PowerShell/psl-pester.git
branch = develop branch = develop
ignore = dirty ignore = dirty
[submodule "src/libpsl-native/test/googletest"]
path = src/libpsl-native/test/googletest
url = https://github.com/google/googletest.git
ignore = dirty
+4 -13
View File
@@ -1,25 +1,16 @@
language: cpp language: cpp
sudo: required sudo: required
dist: trusty dist: trusty
cache:
apt: true
directories:
- $HOME/.nuget
git: git:
submodules: false submodules: false
before_install: before_install:
- git config --global url.git@github.com:.insteadOf https://github.com/ - git config --global url.git@github.com:.insteadOf https://github.com/
- git submodule update --init --recursive -- src/libpsl-native src/windows-build src/Microsoft.PowerShell.Linux.Host/Modules/Pester - git submodule update --init -- src/windows-build src/Modules/Pester src/libpsl-native/test/googletest
- sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list' - ./bootstrap.sh
- sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
- sudo apt-get -qq update
- sudo apt-get install -y dotnet=1.0.0.001675-1
- ./download.sh - ./download.sh
- sudo dpkg -i powershell.deb - sudo dpkg -i ./powershell.deb
script: script:
- powershell -c "Import-Module ./PowerShellGitHubDev.psm1; Start-PSBuild" - powershell -c "Import-Module ./PowerShellGitHubDev.psm1; Start-PSBuild; Start-PSxUnit; Start-PSPester"
- ./pester.sh
- ./xunit.sh
notifications: notifications:
slack: slack:
secure: sKYd4n61+ZFzGZuWGUl8V1kN0NM16wRVOFVlNhlFCwnkrEsKROb++EvXf5uwnKuzxkhEjvPWO+UFgeshQDoR93y4s5YLfhC5JupK4nUzjPzWs208KTrh8u/x9MY8X6Ojxi85EEAiku5GzMoMlkucSStZUYwbIfnelzqdw8uoRwmm2MW4XCPwsuEuDUVghyiva0Mdx1G6MopCrK8T96WywJXT3chhfZQgVt+sQCBt9g+2kjDaObKrzG0P07IVK43ZpDgnu6AoxlyBzIx9mJH2Oa/tki3/kTO72Wcp3ps3qvmiStADamzVKR9p1VlWCLWAd6VOehxuByCGEyujpzk135Wud2DZYO+8LD6inZVhFe3Wt5pCU9BDXZppiATfMCqgXEH7nK54pEn79yHcjthRJ2+Z9ot7As2fu3RSBmTAi8nRP0fxRyX/jctR3S6P0qt0y1ynx9nzBfhmhPQW0PMVazWS/nruQIvK/3iiYXjZxM5bBwIvabmwV00EYeTdbL6ufXWNgQcG1ZWkDsi2I3vst/ytUbHwaFYg83bXWpxg9DCzJeWLVUvE5/3NfBxRAuCTot/fgTEA9IYScvrlL7Q/bT0cOt0vEM98MPf1UO+WP85uxhsRgHtwDEo+jMaL6ZFkPhlV6mmmED4NdY2//a571cLNXdnuMAze5O3TWGBG53g= secure: sKYd4n61+ZFzGZuWGUl8V1kN0NM16wRVOFVlNhlFCwnkrEsKROb++EvXf5uwnKuzxkhEjvPWO+UFgeshQDoR93y4s5YLfhC5JupK4nUzjPzWs208KTrh8u/x9MY8X6Ojxi85EEAiku5GzMoMlkucSStZUYwbIfnelzqdw8uoRwmm2MW4XCPwsuEuDUVghyiva0Mdx1G6MopCrK8T96WywJXT3chhfZQgVt+sQCBt9g+2kjDaObKrzG0P07IVK43ZpDgnu6AoxlyBzIx9mJH2Oa/tki3/kTO72Wcp3ps3qvmiStADamzVKR9p1VlWCLWAd6VOehxuByCGEyujpzk135Wud2DZYO+8LD6inZVhFe3Wt5pCU9BDXZppiATfMCqgXEH7nK54pEn79yHcjthRJ2+Z9ot7As2fu3RSBmTAi8nRP0fxRyX/jctR3S6P0qt0y1ynx9nzBfhmhPQW0PMVazWS/nruQIvK/3iiYXjZxM5bBwIvabmwV00EYeTdbL6ufXWNgQcG1ZWkDsi2I3vst/ytUbHwaFYg83bXWpxg9DCzJeWLVUvE5/3NfBxRAuCTot/fgTEA9IYScvrlL7Q/bT0cOt0vEM98MPf1UO+WP85uxhsRgHtwDEo+jMaL6ZFkPhlV6mmmED4NdY2//a571cLNXdnuMAze5O3TWGBG53g=
+1
View File
@@ -1,4 +1,5 @@
{ {
"version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": ".NET Core Launch", "name": ".NET Core Launch",
+2 -1
View File
@@ -1,7 +1,8 @@
{ {
"version": "0.1.0",
"command": "powershell", "command": "powershell",
"isShellCommand": true, "isShellCommand": true,
"showOutput": "verbose", "showOutput": "always",
"args": [ "-c" ], "args": [ "-c" ],
"tasks": [ "tasks": [
+370 -253
View File
@@ -17,19 +17,19 @@ try {
$IsWindows = $true $IsWindows = $true
} }
function Start-PSBuild
{ function Start-PSBuild {
[CmdletBinding(DefaultParameterSetName='CoreCLR')] [CmdletBinding(DefaultParameterSetName='CoreCLR')]
param( param(
[switch]$Restore, [switch]$Restore,
[switch]$Clean, [switch]$Clean,
[string]$Output,
# These runtimes must match those in project.json # These runtimes must match those in project.json
# We do not use ValidateScript since we want tab completion # We do not use ValidateScript since we want tab completion
[ValidateSet("ubuntu.14.04-x64", [ValidateSet("ubuntu.14.04-x64",
"centos.7.1-x64", "centos.7.1-x64",
"win7-x64", "win7-x64",
"win81-x64",
"win10-x64", "win10-x64",
"osx.10.10-x64", "osx.10.10-x64",
"osx.10.11-x64")] "osx.10.11-x64")]
@@ -44,185 +44,213 @@ function Start-PSBuild
[Parameter(ParameterSetName='FullCLR')] [Parameter(ParameterSetName='FullCLR')]
[ValidateSet("Debug", [ValidateSet("Debug",
"Release")] "Release")]
[string]$msbuildConfiguration = "Release" [string]$msbuildConfiguration = "Release"
) )
function precheck([string]$command, [string]$missedMessage) # simplify ParameterSetNames
{ if ($PSCmdlet.ParameterSetName -eq 'FullCLR') {
$c = Get-Command $command -ErrorAction SilentlyContinue
if (-not $c)
{
Write-Warning $missedMessage
return $false
}
else
{
return $true
}
}
function log([string]$message)
{
Write-Host -Foreground Green $message
}
# simplify ParameterSetNames, set output
if ($PSCmdlet.ParameterSetName -eq 'FullCLR')
{
$FullCLR = $true $FullCLR = $true
} }
if (-not $Output)
{
if ($FullCLR) { $Output = "$PSScriptRoot/binFull" } else { $Output = "$PSScriptRoot/bin" }
}
# verify we have all tools in place to do the build # verify we have all tools in place to do the build
$precheck = precheck 'dotnet' "Build dependency 'dotnet' not found in PATH! See: https://dotnet.github.io/getting-started/" $precheck = precheck 'dotnet' "Build dependency 'dotnet' not found in PATH! See: https://dotnet.github.io/getting-started/"
if ($FullCLR) if ($FullCLR) {
{
# cmake is needed to build powershell.exe # cmake is needed to build powershell.exe
$precheck = $precheck -and (precheck 'cmake' 'cmake not found. You can install it from https://chocolatey.org/packages/cmake.portable') $precheck = $precheck -and (precheck 'cmake' 'cmake not found. You can install it from https://chocolatey.org/packages/cmake.portable')
# msbuild is needed to build powershell.exe # msbuild is needed to build powershell.exe
# msbuild is part of .NET Framework, we can try to get it from well-known location. # msbuild is part of .NET Framework, we can try to get it from well-known location.
if (-not (Get-Command -Name msbuild -ErrorAction Ignore)) if (-not (Get-Command -Name msbuild -ErrorAction Ignore)) {
{
$env:path += ";${env:SystemRoot}\Microsoft.Net\Framework\v4.0.30319" $env:path += ";${env:SystemRoot}\Microsoft.Net\Framework\v4.0.30319"
} }
$precheck = $precheck -and (precheck 'msbuild' 'msbuild not found. Install Visual Studio 2015.') $precheck = $precheck -and (precheck 'msbuild' 'msbuild not found. Install Visual Studio 2015.')
} } elseif ($IsLinux -Or $IsOSX) {
$InstallCommand = if ($IsLinux) {
if (-not $precheck) { return } 'apt-get'
} elseif ($IsOSX) {
'brew'
}
# handle clean foreach ($Dependency in 'cmake', 'make', 'g++') {
if ($Clean) { $precheck = $precheck -and (precheck $Dependency "Build dependency '$Dependency' not found. Run '$InstallCommand install $Dependency'")
Remove-Item -Force -Recurse $Output -ErrorAction SilentlyContinue }
} }
New-Item -Force -Type Directory $Output | Out-Null if (-Not $Runtime) {
$Runtime = dotnet --info | % {
if ($_ -match "RID") {
$_ -split "\s+" | Select-Object -Last 1
}
}
if (-Not $Runtime) {
Write-Warning "Could not determine Runtime Identifier, please update dotnet"
$precheck = $false
} else {
log "Runtime not specified, using $Runtime"
}
}
# Abort if any precheck failed
if (-not $precheck) {
return
}
# define key build variables # define key build variables
if ($FullCLR) if ($FullCLR) {
{
$Top = "$PSScriptRoot\src\Microsoft.PowerShell.ConsoleHost" $Top = "$PSScriptRoot\src\Microsoft.PowerShell.ConsoleHost"
$framework = 'net451' $Framework = 'net451'
} else {
$Top = "$PSScriptRoot/src/Microsoft.PowerShell.Host"
$Framework = 'netstandardapp1.5'
} }
else
{ if ($IsLinux -Or $IsOSX) {
$Top = "$PSScriptRoot/src/Microsoft.PowerShell.Linux.Host" $Configuration = "Linux"
$framework = 'netstandardapp1.5' $Executable = "powershell"
} else {
$Configuration = "Debug"
$Executable = "powershell.exe"
} }
$Arguments = @()
$Arguments += "--framework", $Framework
$Arguments += "--configuration", $Configuration
$Arguments += "--runtime", $Runtime
# FullCLR only builds a library, so there is no runtime component
if ($FullCLR) {
$script:Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework, $Executable)
} else {
$script:Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework, $Runtime, $Executable)
}
Write-Verbose "script:Output is $script:Output"
# handle Restore # handle Restore
if ($Restore -Or -Not (Test-Path "$Top/project.lock.json")) { if ($Restore -Or -Not (Test-Path "$Top/project.lock.json")) {
log "Run dotnet restore" log "Run dotnet restore"
$Arguments = @("--verbosity") $RestoreArguments = @("--verbosity")
if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) {
$Arguments += "Info" } else { $Arguments += "Warning" } $RestoreArguments += "Info"
} else {
$RestoreArguments += "Warning"
}
if ($Runtime) { $Arguments += "--runtime", $Runtime } $RestoreArguments += "$PSScriptRoot"
$Arguments += "$PSScriptRoot" dotnet restore $RestoreArguments
dotnet restore $Arguments
} }
# Build native components # Build native components
if (-not $FullCLR) if ($IsLinux -Or $IsOSX) {
{ $Ext = if ($IsLinux) {
if ($IsLinux -Or $IsOSX) { "so"
log "Start building native components" } elseif ($IsOSX) {
$InstallCommand = if ($IsLinux) { "apt-get" } elseif ($IsOSX) { "brew" } "dylib"
foreach ($Dependency in "cmake", "g++") {
if (-Not (Get-Command $Dependency -ErrorAction SilentlyContinue)) {
throw "Build dependency '$Dependency' not found in PATH! Run '$InstallCommand install $Dependency'"
}
}
$Ext = if ($IsLinux) { "so" } elseif ($IsOSX) { "dylib" }
$Native = "$PSScriptRoot/src/libpsl-native"
$Lib = "$Top/libpsl-native.$Ext"
Write-Verbose "Building $Lib"
try {
Push-Location $Native
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
make test
} finally {
Pop-Location
}
if (-Not (Test-Path $Lib)) { throw "Compilation of $Lib failed" }
} }
}
else $Native = "$PSScriptRoot/src/libpsl-native"
{ $Lib = "$Top/libpsl-native.$Ext"
log "Start building $Lib"
try {
Push-Location $Native
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
make test
} finally {
Pop-Location
}
if (-Not (Test-Path $Lib)) {
throw "Compilation of $Lib failed"
}
} elseif ($FullCLR) {
log "Start building native powershell.exe" log "Start building native powershell.exe"
$build = "$PSScriptRoot/build"
if ($Clean) {
Remove-Item -Force -Recurse $build -ErrorAction SilentlyContinue
}
mkdir $build -ErrorAction SilentlyContinue try {
try Push-Location .\src\powershell-native
{
Push-Location $build
if ($cmakeGenerator) if ($cmakeGenerator) {
{ cmake -G $cmakeGenerator .
cmake -G $cmakeGenerator ..\src\powershell-native } else {
} cmake .
else
{
cmake ..\src\powershell-native
} }
msbuild powershell.vcxproj /p:Configuration=$msbuildConfiguration msbuild powershell.vcxproj /p:Configuration=$msbuildConfiguration
cp -rec $msbuildConfiguration\* $Output
} finally {
Pop-Location
} }
finally { Pop-Location }
} }
log "Building PowerShell" try {
$Arguments = "--framework", $framework, "--output", $Output # Relative paths do not work well if cwd is not changed to project
if ($IsLinux -Or $IsOSX) { $Arguments += "--configuration", "Linux" } log "Run `dotnet build $Arguments` from $pwd"
if ($Runtime) { $Arguments += "--runtime", $Runtime }
if ($FullCLR)
{
# there is a problem with code signing:
# AssemblyKeyFileAttribute file path cannot be correctly located, if `dotnet publish $TOP` syntax is used
# we workaround it with calling `dotnet publish` from $TOP directory instead.
Push-Location $Top Push-Location $Top
} dotnet build $Arguments
else log "PowerShell output: $script:Output"
{ } finally {
$Arguments += $Top Pop-Location
} }
Write-Verbose "Run dotnet publish $Arguments from $pwd" }
# this try-finally is part of workaround about AssemblyKeyFileAttribute issue
try function Get-PSOutput {
{ [CmdletBinding()]param()
dotnet publish $Arguments if (-Not $Output) {
throw '$script:Output is not defined, run Start-PSBuild'
} }
finally
{ $Output
if ($FullCLR) { Pop-Location } }
function Start-PSPester {
[CmdletBinding()]param(
[string]$Flags = '-EnableExit -OutputFile pester-tests.xml -OutputFormat NUnitXml',
[string]$Tests = "*",
[ValidateScript({ Test-Path -PathType Container $_})]
[string]$Directory = "$PSScriptRoot/test/powershell"
)
& (Get-PSOutput) -c "Invoke-Pester $Flags $Directory/$Tests"
if ($LASTEXITCODE -ne 0) {
throw "$LASTEXITCODE Pester tests failed"
} }
} }
function Start-PSPackage
{ function Start-PSxUnit {
[CmdletBinding()]param()
if ($IsWindows) {
throw "xUnit tests are only currently supported on Linux / OS X"
}
$Content = Split-Path -Parent (Get-PSOutput)
$Arguments = "--configuration", "Linux"
try {
Push-Location $PSScriptRoot/test/csharp
dotnet build $Arguments
Copy-Item -ErrorAction SilentlyContinue -Recurse -Path $Content/* -Include Modules,libpsl-native* -Destination "./bin/Linux/netstandardapp1.5/ubuntu.14.04-x64"
dotnet test $Arguments
if ($LASTEXITCODE -ne 0) {
throw "$LASTEXITCODE xUnit tests failed"
}
} finally {
Pop-Location
}
}
function Start-PSPackage {
# PowerShell packages use Semantic Versioning http://semver.org/ # PowerShell packages use Semantic Versioning http://semver.org/
# #
# Ubuntu and OS X packages are supported. # Ubuntu and OS X packages are supported.
param( [CmdletBinding()]param(
[string]$Version, [string]$Version,
[int]$Iteration = 1, [int]$Iteration = 1,
[ValidateSet("deb", "osxpkg", "rpm")] [ValidateSet("deb", "osxpkg", "rpm")]
@@ -285,37 +313,33 @@ function Start-PSPackage
"$PSScriptRoot/package/powershell=/usr/local/bin" "$PSScriptRoot/package/powershell=/usr/local/bin"
} }
function Start-DevPSGitHub
{ function Start-DevPSGitHub {
param( param(
[switch]$ZapDisable, [switch]$ZapDisable,
[string[]]$ArgumentList = '', [string[]]$ArgumentList = '',
[switch]$LoadProfile, [switch]$LoadProfile,
[string]$binDir = "$PSScriptRoot\binFull", [string]$binDir = "$PSScriptRoot\src\Microsoft.PowerShell.ConsoleHost\bin\Debug\net451",
[switch]$NoNewWindow [switch]$NoNewWindow
) )
try try {
{ if ($LoadProfile -eq $false) {
if ($LoadProfile -eq $false)
{
$ArgumentList = @('-noprofile') + $ArgumentList $ArgumentList = @('-noprofile') + $ArgumentList
} }
$env:DEVPATH = $binDir $env:DEVPATH = $binDir
if ($ZapDisable) if ($ZapDisable) {
{
$env:COMPLUS_ZapDisable = 1 $env:COMPLUS_ZapDisable = 1
} }
if (-Not (Test-Path $binDir\powershell.exe.config)) if (-Not (Test-Path $binDir\powershell.exe.config)) {
{
$configContents = @" $configContents = @"
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<configuration> <configuration>
<runtime> <runtime>
<developmentMode developerInstallation="true"/> <developmentMode developerInstallation="true"/>
</runtime> </runtime>
</configuration> </configuration>
"@ "@
$configContents | Out-File -Encoding Ascii $binDir\powershell.exe.config $configContents | Out-File -Encoding Ascii $binDir\powershell.exe.config
@@ -333,71 +357,29 @@ function Start-DevPSGitHub
} }
Start-Process @startProcessArgs Start-Process @startProcessArgs
} } finally {
finally
{
ri env:DEVPATH ri env:DEVPATH
if ($ZapDisable) if ($ZapDisable) {
{
ri env:COMPLUS_ZapDisable ri env:COMPLUS_ZapDisable
} }
} }
} }
## this function is from Dave Wyatt's answer on
## http://stackoverflow.com/questions/22002748/hashtables-from-convertfrom-json-have-different-type-from-powershells-built-in-h
function Convert-PSObjectToHashtable
{
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
{
$collection = @(
foreach ($object in $InputObject) { Convert-PSObjectToHashtable $object }
)
Write-Output -NoEnumerate $collection
}
elseif ($InputObject -is [psobject])
{
$hash = @{}
foreach ($property in $InputObject.PSObject.Properties)
{
$hash[$property.Name] = Convert-PSObjectToHashtable $property.Value
}
$hash
}
else
{
$InputObject
}
}
}
<# <#
.EXAMPLE Copy-SubmoduleFiles # copy files FROM submodule TO src/<project> folders .EXAMPLE Copy-SubmoduleFiles # copy files FROM submodule TO src/<project> folders
.EXAMPLE Copy-SubmoduleFiles -ToSubmodule # copy files FROM src/<project> folders TO submodule .EXAMPLE Copy-SubmoduleFiles -ToSubmodule # copy files FROM src/<project> folders TO submodule
#> #>
function Copy-SubmoduleFiles { function Copy-SubmoduleFiles {
[CmdletBinding()] [CmdletBinding()]
param( param(
[string]$mappingFilePath = "$PSScriptRoot/mapping.json", [string]$mappingFilePath = "$PSScriptRoot/mapping.json",
[switch]$ToSubmodule [switch]$ToSubmodule
) )
if (-not (Test-Path $mappingFilePath)) if (-not (Test-Path $mappingFilePath)) {
{
throw "Mapping file not found in $mappingFilePath" throw "Mapping file not found in $mappingFilePath"
} }
@@ -405,47 +387,38 @@ function Copy-SubmoduleFiles {
# mapping.json assumes the root folder # mapping.json assumes the root folder
Push-Location $PSScriptRoot Push-Location $PSScriptRoot
try try {
{
$m.GetEnumerator() | % { $m.GetEnumerator() | % {
if ($ToSubmodule) if ($ToSubmodule) {
{
cp $_.Value $_.Key -Verbose:$Verbose cp $_.Value $_.Key -Verbose:$Verbose
} } else {
else
{
mkdir (Split-Path $_.Value) -ErrorAction SilentlyContinue > $null mkdir (Split-Path $_.Value) -ErrorAction SilentlyContinue > $null
cp $_.Key $_.Value -Verbose:$Verbose cp $_.Key $_.Value -Verbose:$Verbose
} }
} }
} } finally {
finally
{
Pop-Location Pop-Location
} }
} }
<# <#
.EXAMPLE Create-MappingFile # create mapping.json in the root folder from project.json files .EXAMPLE Create-MappingFile # create mapping.json in the root folder from project.json files
#> #>
function New-MappingFile function New-MappingFile {
{
param( param(
[string]$mappingFilePath = "$PSScriptRoot/mapping.json", [string]$mappingFilePath = "$PSScriptRoot/mapping.json",
[switch]$IgnoreCompileFiles, [switch]$IgnoreCompileFiles,
[switch]$Ignoreresource [switch]$Ignoreresource
) )
function Get-MappingPath([string]$project, [string]$path) function Get-MappingPath([string]$project, [string]$path) {
{ if ($project -match 'TypeCatalogGen') {
if ($project -match 'TypeCatalogGen')
{
return Split-Path $path -Leaf return Split-Path $path -Leaf
} }
if ($project -match 'Microsoft.Management.Infrastructure') if ($project -match 'Microsoft.Management.Infrastructure') {
{
return Split-Path $path -Leaf return Split-Path $path -Leaf
} }
@@ -456,8 +429,7 @@ function New-MappingFile
# assumes the root folder # assumes the root folder
Push-Location $PSScriptRoot Push-Location $PSScriptRoot
try try {
{
$projects = ls .\src\ -Recurse -Depth 2 -Filter 'project.json' $projects = ls .\src\ -Recurse -Depth 2 -Filter 'project.json'
$projects | % { $projects | % {
$project = Split-Path $_.FullName $project = Split-Path $_.FullName
@@ -465,8 +437,7 @@ function New-MappingFile
if (-not $IgnoreCompileFiles) { if (-not $IgnoreCompileFiles) {
$json.compileFiles | % { $json.compileFiles | % {
if ($_) { if ($_) {
if (-not $_.EndsWith('AssemblyInfo.cs')) if (-not $_.EndsWith('AssemblyInfo.cs')) {
{
$fullPath = Join-Path $project (Get-MappingPath -project $project -path $_) $fullPath = Join-Path $project (Get-MappingPath -project $project -path $_)
$mapping[$_.Replace('../', 'src/')] = ($fullPath.Replace("$($pwd.Path)\",'')).Replace('\', '/') $mapping[$_.Replace('../', 'src/')] = ($fullPath.Replace("$($pwd.Path)\",'')).Replace('\', '/')
} }
@@ -485,38 +456,19 @@ function New-MappingFile
} }
} }
} }
} } finally {
finally
{
Pop-Location Pop-Location
} }
Set-Content -Value ($mapping | ConvertTo-Json) -Path $mappingFilePath -Encoding Ascii Set-Content -Value ($mapping | ConvertTo-Json) -Path $mappingFilePath -Encoding Ascii
} }
function Get-InvertedOrderedMap
{
param(
$h
)
$res = [ordered]@{}
foreach ($q in $h.GetEnumerator()) {
if ($res.Contains($q.Value))
{
throw "Cannot invert hashtable: duplicated key $($q.Value)"
}
$res[$q.Value] = $q.Key
}
return $res
}
<# <#
.EXAMPLE Send-GitDiffToSd -diffArg1 45555786714d656bd31cbce67dbccb89c433b9cb -diffArg2 45555786714d656bd31cbce67dbccb89c433b9cb~1 -pathToAdmin d:\e\ps_dev\admin .EXAMPLE Send-GitDiffToSd -diffArg1 45555786714d656bd31cbce67dbccb89c433b9cb -diffArg2 45555786714d656bd31cbce67dbccb89c433b9cb~1 -pathToAdmin d:\e\ps_dev\admin
Apply a signle commit to admin folder Apply a signle commit to admin folder
#> #>
function Send-GitDiffToSd function Send-GitDiffToSd {
{
param( param(
[Parameter(Mandatory)] [Parameter(Mandatory)]
[string]$diffArg1, [string]$diffArg1,
@@ -533,32 +485,197 @@ function Send-GitDiffToSd
$affectedFiles = git diff --name-only $diffArg1 $diffArg2 $affectedFiles = git diff --name-only $diffArg1 $diffArg2
$rev = Get-InvertedOrderedMap $m $rev = Get-InvertedOrderedMap $m
foreach ($file in $affectedFiles) { foreach ($file in $affectedFiles) {
if ($rev.Contains) if ($rev.Contains) {
{
$sdFilePath = Join-Path $pathToAdmin $rev[$file].Substring('src/monad/'.Length) $sdFilePath = Join-Path $pathToAdmin $rev[$file].Substring('src/monad/'.Length)
$diff = git diff $diffArg1 $diffArg2 -- $file $diff = git diff $diffArg1 $diffArg2 -- $file
if ($diff) if ($diff) {
{
Write-Host -Foreground Green "Apply patch to $sdFilePath" Write-Host -Foreground Green "Apply patch to $sdFilePath"
Set-Content -Value $diff -Path $env:TEMP\diff -Encoding Ascii Set-Content -Value $diff -Path $env:TEMP\diff -Encoding Ascii
if ($WhatIf) if ($WhatIf) {
{
Write-Host -Foreground Green "Patch content" Write-Host -Foreground Green "Patch content"
cat $env:TEMP\diff cat $env:TEMP\diff
} else {
& $patchPath --binary -p1 $sdFilePath $env:TEMP\diff
} }
else } else {
{
& $patchPath --binary -p1 $sdFilePath $env:TEMP\diff
}
}
else
{
Write-Host -Foreground Green "No changes in $file" Write-Host -Foreground Green "No changes in $file"
} }
} } else {
else
{
Write-Host -Foreground Green "Ignore changes in $file, because there is no mapping for it" Write-Host -Foreground Green "Ignore changes in $file, because there is no mapping for it"
} }
} }
} }
function Start-ResGen
{
@("Microsoft.PowerShell.Commands.Management",
"Microsoft.PowerShell.Commands.Utility",
"Microsoft.PowerShell.ConsoleHost",
"Microsoft.PowerShell.CoreCLR.Eventing",
"Microsoft.PowerShell.Security",
"System.Management.Automation") | % {
$module = $_
ls "$PSScriptRoot/src/$module/resources" | % {
$className = $_.Name.Replace('.resx', '')
$xml = [xml](cat -raw $_.FullName)
$genSource = Get-StronglyTypeCsFileForResx -xml $xml -ModuleName $module -ClassName $className
$outPath = "$PSScriptRoot/src/windows-build/gen/$module/$className.cs"
log "ResGen for $outPath"
mkdir -ErrorAction SilentlyContinue (Split-Path $outPath) > $null
Set-Content -Encoding Ascii -Path $outPath -Value $genSource
}
}
}
function script:log([string]$message) {
Write-Host -Foreground Green $message
}
function script:precheck([string]$command, [string]$missedMessage) {
$c = Get-Command $command -ErrorAction SilentlyContinue
if (-not $c) {
Write-Warning $missedMessage
return $false
} else {
return $true
}
}
function script:Get-InvertedOrderedMap {
param(
$h
)
$res = [ordered]@{}
foreach ($q in $h.GetEnumerator()) {
if ($res.Contains($q.Value)) {
throw "Cannot invert hashtable: duplicated key $($q.Value)"
}
$res[$q.Value] = $q.Key
}
return $res
}
## this function is from Dave Wyatt's answer on
## http://stackoverflow.com/questions/22002748/hashtables-from-convertfrom-json-have-different-type-from-powershells-built-in-h
function script:Convert-PSObjectToHashtable {
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process {
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) {
$collection = @(
foreach ($object in $InputObject) { Convert-PSObjectToHashtable $object }
)
Write-Output -NoEnumerate $collection
} elseif ($InputObject -is [psobject]) {
$hash = @{}
foreach ($property in $InputObject.PSObject.Properties)
{
$hash[$property.Name] = Convert-PSObjectToHashtable $property.Value
}
$hash
} else {
$InputObject
}
}
}
function script:Get-StronglyTypeCsFileForResx
{
param($xml, $ModuleName, $ClassName)
$body = @'
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a Start-ResGen funciton from PowerShellGitHubDev.psm1.
// To add or remove a member, edit your .ResX file then rerun Start-ResGen.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class {0} {{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal {0}() {{
}}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {{
get {{
if (object.ReferenceEquals(resourceMan, null)) {{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("{1}.resources.{0}", typeof({0}).GetTypeInfo().Assembly);
resourceMan = temp;
}}
return resourceMan;
}}
}}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {{
get {{
return resourceCulture;
}}
set {{
resourceCulture = value;
}}
}}
{2}
}}
'@
$entry = @'
/// <summary>
/// Looks up a localized string similar to {1}
/// </summary>
internal static string {0} {{
get {{
return ResourceManager.GetString("{0}", resourceCulture);
}}
}}
'@
$entries = $xml.root.data | % {
if ($_) {
$val = $_.value.Replace("`n", "`n ///")
$name = $_.name.Replace(' ', '_')
$entry -f $name,$val
}
} | Out-String
$body -f $ClassName,$ModuleName,$entries
}
+8 -9
View File
@@ -6,9 +6,6 @@ environment:
priv_key: priv_key:
secure: <encryped-value> secure: <encryped-value>
cache:
- '%LocalAppData%\Microsoft\dotnet'
notifications: notifications:
- provider: Slack - provider: Slack
incoming_webhook: incoming_webhook:
@@ -20,9 +17,9 @@ install:
- ps: $fileContent += "`n-----END RSA PRIVATE KEY-----`n" - ps: $fileContent += "`n-----END RSA PRIVATE KEY-----`n"
- ps: Set-Content c:\users\appveyor\.ssh\id_rsa $fileContent - ps: Set-Content c:\users\appveyor\.ssh\id_rsa $fileContent
- git config --global url.git@github.com:.insteadOf https://github.com/ - git config --global url.git@github.com:.insteadOf https://github.com/
- git submodule update --init --recursive -- src/windows-build src/Microsoft.PowerShell.Linux.Host/Modules/Pester - git submodule update --init -- src/windows-build src/Modules/Pester
- ps: Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1 - ps: Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1
- ps: ./install.ps1 -version 1.0.0.001888 - ps: ./install.ps1 -version 1.0.0-beta-002198
build_script: build_script:
- ps: | - ps: |
@@ -38,15 +35,17 @@ test_script:
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# #
# CoreCLR # CoreCLR
$env:CoreOutput = "$pwd\src\Microsoft.PowerShell.Host\bin\Debug\netstandardapp1.5\win81-x64"
Write-Host -Foreground Green 'Run CoreCLR tests' Write-Host -Foreground Green 'Run CoreCLR tests'
$testResultsFile = "$pwd\TestsResults.xml" $testResultsFile = "$pwd\TestsResults.xml"
.\bin\powershell.exe --noprofile -c "Import-Module .\bin\Modules\Microsoft.PowerShell.Platform; Invoke-Pester test/powershell -OutputFormat NUnitXml -OutputFile $testResultsFile" & ("$env:CoreOutput\powershell.exe") -c "Invoke-Pester test/powershell -OutputFormat NUnitXml -OutputFile $testResultsFile"
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile))
# #
# FullCLR # FullCLR
$env:FullOutput = "$pwd\src\Microsoft.PowerShell.ConsoleHost\bin\Debug\net451"
Write-Host -Foreground Green 'Run FullCLR tests' Write-Host -Foreground Green 'Run FullCLR tests'
$testResultsFileFullCLR = "$pwd\TestsResults.FullCLR.xml" $testResultsFileFullCLR = "$pwd\TestsResults.FullCLR.xml"
Start-DevPSGitHub -binDir $pwd\binFull -NoNewWindow -ArgumentList '-command', "Import-Module .\src\Microsoft.PowerShell.Linux.Host\Modules\Pester; Import-Module .\bin\Modules\Microsoft.PowerShell.Platform; Invoke-Pester test/fullCLR -OutputFormat NUnitXml -OutputFile $testResultsFileFullCLR" Start-DevPSGitHub -binDir $env:FullOutput -NoNewWindow -ArgumentList '-command', "Import-Module .\src\Modules\Pester; Import-Module .\bin\Modules\Microsoft.PowerShell.Platform; Invoke-Pester test/fullCLR -OutputFormat NUnitXml -OutputFile $testResultsFileFullCLR"
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFileFullCLR)) (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFileFullCLR))
# #
# Fail the build, if tests failed # Fail the build, if tests failed
@@ -71,8 +70,8 @@ on_finish:
$zipFilePath = Join-Path $pwd "$name.zip" $zipFilePath = Join-Path $pwd "$name.zip"
$zipFileFullPath = Join-Path $pwd "$name.FullCLR.zip" $zipFileFullPath = Join-Path $pwd "$name.FullCLR.zip"
Add-Type -assemblyname System.IO.Compression.FileSystem Add-Type -assemblyname System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory("$pwd\bin", $zipFilePath) [System.IO.Compression.ZipFile]::CreateFromDirectory($env:CoreOutput, $zipFilePath)
[System.IO.Compression.ZipFile]::CreateFromDirectory("$pwd\binFull", $zipFileFullPath) [System.IO.Compression.ZipFile]::CreateFromDirectory($env:FullOutput, $zipFileFullPath)
@( @(
# You can add other artifacts here # You can add other artifacts here
Executable
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
echo "Installing build dependencies"
curl http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt-get update -qq
sudo apt-get install -y wget make g++ cmake \
libc6 libgcc1 libstdc++6 \
libcurl3 libgssapi-krb5-2 libicu52 liblldb-3.6 liblttng-ust0 libssl1.0.0 libunwind8 libuuid1 zlib1g clang-3.5
wget -P /tmp https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-host-ubuntu-x64.latest.deb
sudo dpkg -i /tmp/dotnet-host-ubuntu-x64.latest.deb
wget -P /tmp https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-sharedframework-ubuntu-x64.latest.deb
sudo dpkg -i /tmp/dotnet-sharedframework-ubuntu-x64.latest.deb
wget -P /tmp https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-sdk-ubuntu-x64.latest.deb
sudo dpkg -i /tmp/dotnet-sdk-ubuntu-x64.latest.deb
+1 -1
View File
@@ -5,7 +5,7 @@ hash cmake 2>/dev/null || { echo >&2 "No cmake, please run 'sudo apt-get install
hash g++ 2>/dev/null || { echo >&2 "No g++, please run 'sudo apt-get install g++'"; exit 1; } hash g++ 2>/dev/null || { echo >&2 "No g++, please run 'sudo apt-get install g++'"; exit 1; }
hash dotnet 2>/dev/null || { echo >&2 "No dotnet, please visit https://dotnet.github.io/getting-started/"; exit 1; } hash dotnet 2>/dev/null || { echo >&2 "No dotnet, please visit https://dotnet.github.io/getting-started/"; exit 1; }
TOP="$(pwd)/src/Microsoft.PowerShell.Linux.Host" TOP="$(pwd)/src/Microsoft.PowerShell.Host"
# Test for lock file # Test for lock file
test -r "$TOP/project.lock.json" || { echo >&2 "Please run 'dotnet restore' to download .NET Core packages"; exit 2; } test -r "$TOP/project.lock.json" || { echo >&2 "Please run 'dotnet restore' to download .NET Core packages"; exit 2; }
+50 -53
View File
@@ -21,27 +21,21 @@ components. Install the following packages for the toolchain:
- `cmake` - `cmake`
- `make` - `make`
- `g++` - `g++`
- `libunwind8`
- `libicu52`
And for debgging: Unfortunately, the `apt-get` feed for `dotnet` has been deprecated,
and the latest version is only distributed in the form of three
separate packages, which require manual dependency resolution.
- `strace` **To ease this process, just run `./bootstrap.sh` and enter password
- `lldb-3.6` for `sudo` when prompted.**
In order to get `dotnet`, we need to add an additional package source: The [bootstrap script](../../bootstrap.sh) does the following:
```sh - Adds the LLVM package feed
sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list' - Installs our dependencies combined with the dependencies of the .NET
sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893 CLI toolchain via `apt-get`
sudo apt-get update - Installs the .NET CLI host, shared framework, and SDK by downloading
``` the three `.deb` packages to `/tmp` and using `dpkg -i`
Then install the packages you need:
```sh
sudo apt-get install dotnet cmake make g++ libunwind8 libicu52 strace lldb-3.6
```
[dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli [dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli
[CMake]: https://cmake.org/cmake/help/v2.8.12/cmake.html [CMake]: https://cmake.org/cmake/help/v2.8.12/cmake.html
@@ -52,21 +46,12 @@ sudo apt-get install dotnet cmake make g++ libunwind8 libicu52 strace lldb-3.6
If you have any problems installing `dotnet`, please see their If you have any problems installing `dotnet`, please see their
[documentation][cli-docs]. [documentation][cli-docs].
The version of .NET CLI is very important, you want a recent build of The version of .NET CLI is very important, you need a recent build of
1.0.0 (**not** 1.0.1). 1.0.0 (**not** 1.0.1).
Previous installations of DNX, `dnvm`, or older installations of .NET Previous installations of DNX, `dnvm`, or older installations of .NET
CLI can cause odd failures when running. Please check your version. CLI can cause odd failures when running. Please check your version and
uninstall prior any prior versions.
The drawback of using the feed is that it gets out of date. To upgrade
the package, install it by hand. Unfortunately, `dpkg` does not handle
dependency resolution, so it is recommended to first install the older
version from the feed, and then upgrade it.
```sh
wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-ubuntu-x64.latest.deb
sudo dpkg -i ./dotnet-ubuntu-x64.latest.deb
```
[cli-docs]: https://dotnet.github.io/getting-started/ [cli-docs]: https://dotnet.github.io/getting-started/
@@ -79,22 +64,22 @@ the submodules:
```sh ```sh
git clone https://github.com/PowerShell/PowerShell.git git clone https://github.com/PowerShell/PowerShell.git
cd PowerShell cd PowerShell
git submodule update --init --recursive -- src/windows-build src/libpsl-native src/Microsoft.PowerShell.Linux.Host/Modules/Pester git submodule update --init -- src/windows-build src/Modules/Pester src/libpsl-native/test/googletest
``` ```
Build using our module Build using our module
====================== ======================
We maintain a `PowerShellGitHubDev.psm1` PowerShell module with the We maintain a [PowerShell module](../../PowerShellGitHubDev.psm1) with
function `Start-PSBuild` to build PowerShell. Since this is PowerShell the function `Start-PSBuild` to build PowerShell. Since this is
code, it requires self-hosting. Fortunately, this is as easy as PowerShell code, it requires self-hosting. Fortunately, this is as
downloading and installing the package. Unfortunately, while the easy as downloading and installing the package. Unfortunately, while
repository is still private, the package cannot be downloaded as the repository is still private, the package cannot be downloaded as
simply as with `wget`. We have a script that wraps the GitHub API and simply as with `wget`. We have a script that wraps the GitHub API and
uses a personal access token to authorize and obtain the package. uses a personal access token to authorize and obtain the package.
> You can alternativelly download via a browser and upload it to your > You can alternativelly download via a browser and upload it to your
> box via some other method > box via some other method.
```sh ```sh
GITHUB_TOKEN=<replace with your token> ./download.sh GITHUB_TOKEN=<replace with your token> ./download.sh
@@ -106,18 +91,23 @@ You should now be in a `powershell` console host that is installed
separately from any development copy you're about to build. Just separately from any development copy you're about to build. Just
import our module and build! import our module and build!
> If you cannot or do not want to self-host, `Start-PSBuild` is just a
> convenience; you can execute each step of the build process yourself
> in Bash; see [Build manually][#Build manually] below.
```powershell ```powershell
Import-Module ./PowerShellGitHubDev.psm1 Import-Module ./PowerShellGitHubDev.psm1
Start-PSBuild Start-PSBuild
``` ```
Congratulations! If everything went right, PowerShell is now built and Congratulations! If everything went right, PowerShell is now built.
executable as `./bin/powershell`. The `Start-PSBuild` script will output the location of the executable:
`./src/Microsoft.PowerShell.Host/bin/Linux/netstandardapp1.5/ubuntu.14.04-x64/powershell`.
> Note that the `./build.sh` script is deprecated and may be removed > Note that the `./build.sh` script is deprecated and will be removed
You can run our cross-platform Pester tests with `./bin/powershell -c You can run our cross-platform Pester tests with `Start-PSPester`, and
"Invoke-Pester test/powershell"`. our xUnit tests with `Start-PSxUnit`.
Build manually Build manually
============== ==============
@@ -138,29 +128,36 @@ make test
popd popd
``` ```
This library will be emitted in the This library will be emitted in the `src/Microsoft.PowerShell.Host`
`src/Microsoft.PowerShell.Linux.Host` project, where `dotnet` consumes project, where `dotnet` consumes it as "content" and thus
it as "content" and thus automatically deploys it. automatically deploys it.
Build the managed projects Build the managed projects
-------------------------- --------------------------
The `Linux.Host`, while poorly named, is the cross-platform host for The `Microsoft.PowerShell.Host` project is the cross-platform host for
PowerShell targetting .NET Core. It is the top level project, so PowerShell targetting .NET Core. It is the top level project, so
`dotnet publish` transitively builds all its dependencies, and emits a `dotnet build` transitively builds all its dependencies, and emits a
`powershell` executable and all necessary libraries (both native and `powershell` executable. The `--configuration Linux` flag is
managed) in a flat directory (specified with `--output`, otherwise
automatically nested depending on runtime, configuration, and
framework, see [issue #685][]). The `--configuration Linux` flag is
necessary to ensure that the preprocessor definition `LINUX` is necessary to ensure that the preprocessor definition `LINUX` is
defined (see [issue #673][]). defined (see [issue #673][]).
```sh ```sh
dotnet restore dotnet restore
dotnet publish --output bin --configuration Linux src/Microsoft.PowerShell.Linux.Host cd src/Microsoft.PowerShell.Host
dotnet build --configuration Linux
``` ```
PowerShell and all necessary components should now be in the `bin` folder. The executable will be in
`./bin/[configuration]/[framework]/[rid]/[binary name]`, where our
configuration is `Linux`, framework is `netstandardapp1.5`, runtime
identifier is `ubuntu.14.04-x64`, and binary name is `powershell`. The
function `Get-PSOutput` will return the path to the executable; thus
you can execute the development copy via `& (Get-PSOutput)`.
For deploying PowerShell, `dotnet publish` will emit a `publish`
directory that contains a flat list of every dependency required for
PowerShell. This can be copied to, say, `/usr/local/share/powershell`
or packaged.
[issue #673]: https://github.com/PowerShell/PowerShell/issues/673 [issue #673]: https://github.com/PowerShell/PowerShell/issues/673
[issue #685]: https://github.com/PowerShell/PowerShell/issues/685
+10 -2
View File
@@ -18,8 +18,8 @@ dependencies.
brew install openssl cmake wget brew install openssl cmake wget
``` ```
Instead of using .NET CLI's Ubuntu package feed, you will want to use Instead of using Linux `./bootstrap.sh` to install .NET CLI's Ubuntu
the official PKG installer. packages, you will want to use the official PKG installer for OS X.
```sh ```sh
wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-dev-osx-x64.latest.pkg wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-dev-osx-x64.latest.pkg
@@ -35,3 +35,11 @@ Instead of installing the Ubuntu package of PowerShell, download the
`pkg` from our GitHub releases page using your browser, complete the `pkg` from our GitHub releases page using your browser, complete the
wizard, start a `powershell` session, and use `Start-PSBuild` from the wizard, start a `powershell` session, and use `Start-PSBuild` from the
module. module.
The output directory will be slightly different because your runtime
identifier is different. PowerShell will be at
`./src/Microsoft.PowerShell.Host/bin/Linux/netstandardapp1.5/osx.10.11-x64/powershell`,
or `osx.10.10` depending on your operating system version. Note that
configration is still `Linux` because it would be silly to make yet
another separate configuration when it's used soley to work-around a
CLI issue.
+22 -9
View File
@@ -20,8 +20,8 @@ it to your PowerShell session's path:
```powershell ```powershell
Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1 Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1
./install.ps1 -version 1.0.0.001888 ./install.ps1 -version 1.0.0-beta-002198
$env:Path += ";$env:LocalAppData\Microsoft\dotnet\cli $env:Path += ";$env:LocalAppData\Microsoft\dotnet\cli"
``` ```
If you have any problems installing `dotnet`, please see their If you have any problems installing `dotnet`, please see their
@@ -52,14 +52,14 @@ the submodules:
```sh ```sh
git clone https://github.com/PowerShell/PowerShell.git git clone https://github.com/PowerShell/PowerShell.git
cd PowerShell cd PowerShell
git submodule update --init -- src/windows-build src/Microsoft.PowerShell.Linux.Host/Modules/Pester git submodule update --init -- src/windows-build src/Modules/Pester
``` ```
Build using our module Build using our module
====================== ======================
We maintain a `PowerShellGitHubDev.psm1` PowerShell module with the We maintain a [PowerShell module](../../PowerShellGitHubDev.psm1) with
function `Start-PSBuild` to build PowerShell. the function `Start-PSBuild` to build PowerShell.
```powershell ```powershell
Import-Module ./PowerShellGitHubDev.psm1 Import-Module ./PowerShellGitHubDev.psm1
@@ -67,9 +67,22 @@ Start-PSBuild
``` ```
Congratulations! If everything went right, PowerShell is now built and Congratulations! If everything went right, PowerShell is now built and
executable as `./bin/powershell.exe`. executable as `./src/Microsoft.PowerShell.Host/bin/Debug/netstandardapp1.5/win10-x64/powershell`.
> The cross-platform host has built-in documentation via `--help`. This location is of the form
`./[project]/bin/[configuration]/[framework]/[rid]/[binary name]`, and
our project is `Microsoft.PowerShell.Host`, configuration is `Debug`
by default, framework is `netstandardapp1.5`, runtime identifier is
**probably** `win10-x64` (but will depend on your operating system;
don't worry, `dotnet --info` will tell you what it was), and binary
name is `powershell`. The function `Get-PSOutput` will return the path
to the executable; thus you can execute the development copy via `&
(Get-PSOutput)`.
You can run our cross-platform Pester tests with `./bin/powershell.exe The `Microsoft.PowerShell.Host` project is the cross-platform host for
-c "Invoke-Pester test/powershell"`. PowerShell targetting .NET Core. It is the top level project, so
`dotnet build` transitively builds all its dependencies, and emits a
`powershell` executable. The cross-platform host has built-in
documentation via `--help`.
You can run our cross-platform Pester tests with `Start-PSPester`.
+29 -7
View File
@@ -3,7 +3,7 @@ Build PowerShell on Windows for .NET Full
This guide supplements the This guide supplements the
[Windows .NET Core instructions](./windows-core.md), as building the [Windows .NET Core instructions](./windows-core.md), as building the
.NET 4.5.1 (desktop) version is nearly identical. .NET 4.5.1 (desktop) version is pretty similar.
Environment Environment
=========== ===========
@@ -46,21 +46,43 @@ Build using our module
====================== ======================
Use `Start-PSBuild -FullCLR` from the `PowerShellGitHubDev.psm1` Use `Start-PSBuild -FullCLR` from the `PowerShellGitHubDev.psm1`
module. The bits will be published to `binFull`. module.
Because the `ConsoleHost` project (*not* the `Host` project) is a
library and not an application (in the sense that .NET CLI does not
emit a native executable using .NET Core's `corehost`), it targets the
framework `netstandard1.5`, *not* `netstandardapp1.5`, and the build
output will *not* have a runtime identifier in the path.
Thus the output location of `powershell.exe` will be
`./src/Microsoft.PowerShell.ConsoleHost/bin/Debug/netstandardapp1.5/powershell.exe`
While building is easy, running FullCLR version is not as simple as While building is easy, running FullCLR version is not as simple as
CoreCLR version. CoreCLR version.
If you just run ~~`.\binFull\powershell.exe`~~, you will get a If you just run ~~`./powershell.exe`~~, you will get a `powershell`
`powershell` process, but all the interesting DLLs (i.e. process, but all the interesting DLLs (such as
`System.Management.Automation.dll`) would be loaded from the GAC, not `System.Management.Automation.dll`) would be loaded from the Global
your `binFull` build directory. Assembly Cache (GAC), not your output directory.
[@lzybkr](https://github.com/lzybkr) wrote a module to deal with it [@lzybkr](https://github.com/lzybkr) wrote a module to deal with it
and run side-by-side. and run side-by-side.
```powershell ```powershell
Start-DevPSGithub -binDir $pwd\binFull Start-DevPSGithub
```
This command has a reasonable default to run `powershell.exe` from the build output folder.
If you are building an unusual configuration (i.e. not `Debug`), you can explicitly specify path to the bin directory
```powershell
Start-DevPSGithub -binDir .\src\Microsoft.PowerShell.ConsoleHost\bin\Debug\net451
```
Or more programmatically:
```powershell
Start-DevPSGithub -binDir (Split-Path -Parent (Get-PSOutput))
``` ```
The default for `powershell.exe` that **we build** is x86. See The default for `powershell.exe` that **we build** is x86. See
+16
View File
@@ -42,3 +42,19 @@ provide a PID. (Please be careful not to commit such a change).
[vscode]: https://code.visualstudio.com/ [vscode]: https://code.visualstudio.com/
[OmniSharp]: https://github.com/OmniSharp/omnisharp-vscode [OmniSharp]: https://github.com/OmniSharp/omnisharp-vscode
[vscclrdebugger]: http://aka.ms/vscclrdebugger [vscclrdebugger]: http://aka.ms/vscclrdebugger
corehost
--------
The native executable prouduced by .NET CLI will produce trace output
if launched with `COREHOST_TRACE=1 ./powershell`.
CoreCLR PAL
-----------
The native code in the CLR has debug channels to selectively output
information to the console. These are controlled by the
`PAL_DBG_CHANNELS`, e.g., `export PAL_DBG_CHANNELS="+all.all"`, as
detailed in the `dbgmsg.h` [header][].
[header]: https://github.com/dotnet/coreclr/blob/release/1.0.0-rc2/src/pal/src/include/pal/dbgmsg.h
+25 -4
View File
@@ -1137,10 +1137,10 @@
"src/monad/monad/src/engine/resources/Logging.resx": "src/System.Management.Automation/resources/Logging.resx", "src/monad/monad/src/engine/resources/Logging.resx": "src/System.Management.Automation/resources/Logging.resx",
"src/monad/monad/src/engine/resources/Metadata.resx": "src/System.Management.Automation/resources/Metadata.resx", "src/monad/monad/src/engine/resources/Metadata.resx": "src/System.Management.Automation/resources/Metadata.resx",
"src/monad/monad/src/engine/resources/MiniShellErrors.resx": "src/System.Management.Automation/resources/MiniShellErrors.resx", "src/monad/monad/src/engine/resources/MiniShellErrors.resx": "src/System.Management.Automation/resources/MiniShellErrors.resx",
"src/monad/monad/src/engine/resources/modules.resx": "src/System.Management.Automation/resources/modules.resx", "src/monad/monad/src/engine/resources/modules.resx": "src/System.Management.Automation/resources/Modules.resx",
"src/monad/monad/src/engine/resources/MshHostRawUserInterfaceStrings.resx": "src/System.Management.Automation/resources/MshHostRawUserInterfaceStrings.resx", "src/monad/monad/src/engine/resources/MshHostRawUserInterfaceStrings.resx": "src/System.Management.Automation/resources/MshHostRawUserInterfaceStrings.resx",
"src/monad/monad/src/engine/resources/MshSignature.resx": "src/System.Management.Automation/resources/MshSignature.resx", "src/monad/monad/src/engine/resources/MshSignature.resx": "src/System.Management.Automation/resources/MshSignature.resx",
"src/monad/monad/src/engine/resources/MshSnapinCmdletResources.resx": "src/System.Management.Automation/resources/MshSnapinCmdletResources.resx", "src/monad/monad/src/engine/resources/MshSnapinCmdletResources.resx": "src/System.Management.Automation/resources/MshSnapInCmdletResources.resx",
"src/monad/monad/src/engine/resources/MshSnapinInfo.resx": "src/System.Management.Automation/resources/MshSnapinInfo.resx", "src/monad/monad/src/engine/resources/MshSnapinInfo.resx": "src/System.Management.Automation/resources/MshSnapinInfo.resx",
"src/monad/monad/src/engine/resources/NativeCP.resx": "src/System.Management.Automation/resources/NativeCP.resx", "src/monad/monad/src/engine/resources/NativeCP.resx": "src/System.Management.Automation/resources/NativeCP.resx",
"src/monad/monad/src/engine/resources/ParameterBinderStrings.resx": "src/System.Management.Automation/resources/ParameterBinderStrings.resx", "src/monad/monad/src/engine/resources/ParameterBinderStrings.resx": "src/System.Management.Automation/resources/ParameterBinderStrings.resx",
@@ -1155,7 +1155,7 @@
"src/monad/monad/src/engine/resources/PSDataBufferStrings.resx": "src/System.Management.Automation/resources/PSDataBufferStrings.resx", "src/monad/monad/src/engine/resources/PSDataBufferStrings.resx": "src/System.Management.Automation/resources/PSDataBufferStrings.resx",
"src/monad/monad/src/engine/resources/PSListModifierStrings.resx": "src/System.Management.Automation/resources/PSListModifierStrings.resx", "src/monad/monad/src/engine/resources/PSListModifierStrings.resx": "src/System.Management.Automation/resources/PSListModifierStrings.resx",
"src/monad/monad/src/engine/resources/RegistryProviderStrings.resx": "src/System.Management.Automation/resources/RegistryProviderStrings.resx", "src/monad/monad/src/engine/resources/RegistryProviderStrings.resx": "src/System.Management.Automation/resources/RegistryProviderStrings.resx",
"src/monad/monad/src/engine/resources/remotingerroridstrings.resx": "src/System.Management.Automation/resources/remotingerroridstrings.resx", "src/monad/monad/src/engine/resources/remotingerroridstrings.resx": "src/System.Management.Automation/resources/RemotingErrorIdStrings.resx",
"src/monad/monad/src/engine/resources/RunspaceInit.resx": "src/System.Management.Automation/resources/RunspaceInit.resx", "src/monad/monad/src/engine/resources/RunspaceInit.resx": "src/System.Management.Automation/resources/RunspaceInit.resx",
"src/monad/monad/src/engine/resources/RunspacePoolStrings.resx": "src/System.Management.Automation/resources/RunspacePoolStrings.resx", "src/monad/monad/src/engine/resources/RunspacePoolStrings.resx": "src/System.Management.Automation/resources/RunspacePoolStrings.resx",
"src/monad/monad/src/engine/resources/RunspaceStrings.resx": "src/System.Management.Automation/resources/RunspaceStrings.resx", "src/monad/monad/src/engine/resources/RunspaceStrings.resx": "src/System.Management.Automation/resources/RunspaceStrings.resx",
@@ -1180,5 +1180,26 @@
"src/monad/monad/nttargets/assemblies/nativemsh/pwrshcommon/WinSystemCallFacade.h": "src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h", "src/monad/monad/nttargets/assemblies/nativemsh/pwrshcommon/WinSystemCallFacade.h": "src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h",
"src/monad/monad/nttargets/assemblies/nativemsh/pwrshexe/MainEntry.cpp": "src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp", "src/monad/monad/nttargets/assemblies/nativemsh/pwrshexe/MainEntry.cpp": "src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp",
"src/monad/monad/nttargets/assemblies/nativemsh/pwrshexe/OutputWriter.h": "src/powershell-native/nativemsh/pwrshexe/OutputWriter.h", "src/monad/monad/nttargets/assemblies/nativemsh/pwrshexe/OutputWriter.h": "src/powershell-native/nativemsh/pwrshexe/OutputWriter.h",
"src/monad/monad/src/graphicalhost/visualstudiopublic.snk": "src/signing/visualstudiopublic.snk" "src/monad/monad/src/graphicalhost/visualstudiopublic.snk": "src/signing/visualstudiopublic.snk",
"src/monad/monad/miscfiles/modules/AppxProvider/AppxProvider.psd1": "src/Modules/AppxProvider/AppxProvider.psd1",
"src/monad/monad/miscfiles/modules/AppxProvider/AppxProvider.psm1": "src/Modules/AppxProvider/AppxProvider.psm1",
"src/monad/monad/miscfiles/modules/AppxProvider/AppxProvider.Resource.psd1": "src/Modules/AppxProvider/AppxProvider.Resource.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Archive/ArchiveResources.psd1": "src/Modules/Microsoft.PowerShell.Archive/ArchiveResources.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psd1": "src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1": "src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Diagnostics/CoreClr/Microsoft.PowerShell.Diagnostics.psd1": "src/Microsoft.PowerShell.Host/Modules/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1": "src/Microsoft.PowerShell.ConsoleHost/Modules/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1": "src/Modules/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1": "src/Modules/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1": "src/Modules/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Utility/CoreClr/Microsoft.PowerShell.Utility.psd1": "src/Microsoft.PowerShell.Host/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1": "src/Microsoft.PowerShell.ConsoleHost/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1",
"src/monad/monad/miscfiles/modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1": "src/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1",
"src/monad/monad/miscfiles/modules/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1": "src/Modules/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1",
"src/monad/monad/miscfiles/modules/PSDiagnostics/PSDiagnostics.psd1": "src/Modules/PSDiagnostics/PSDiagnostics.psd1",
"src/monad/monad/miscfiles/modules/PSDiagnostics/PSDiagnostics.psm1": "src/Modules/PSDiagnostics/PSDiagnostics.psm1",
"src/monad/monad/miscfiles/modules/PSGet/PSGet.Format.ps1xml": "src/Modules/PSGet/PSGet.Format.ps1xml",
"src/monad/monad/miscfiles/modules/PSGet/PSGet.psd1": "src/Modules/PSGet/PSGet.psd1",
"src/monad/monad/miscfiles/modules/PSGet/PSGet.Resource.psd1": "src/Modules/PSGet/PSGet.Resource.psd1",
"src/monad/monad/miscfiles/modules/PSGet/PSModule.psm1": "src/Modules/PSGet/PSModule.psm1"
} }
-12
View File
@@ -1,12 +0,0 @@
#!/usr/bin/env bash
test -x bin/powershell || { echo >&2 "No bin/powershell, please run './build.sh'"; exit 1; }
./bin/powershell --noprofile -c "Import-Module Microsoft.PowerShell.Platform; Invoke-Pester test/powershell/$1 -OutputFile pester-tests.xml -OutputFormat NUnitXml -EnableExit"
failed_tests=$?
# XML files are not executable
chmod -x pester-tests.xml
# Return number of failed tests as exit code (more than 0 will be an error)
exit $failed_tests
@@ -36,5 +36,5 @@
} }
}, },
"compile": [ "../windows-build/gen/COMMANDS_MANAGEMENT/*.cs" ] "compile": [ "../windows-build/gen/Microsoft.PowerShell.Commands.Management/*.cs" ]
} }
@@ -2507,21 +2507,25 @@ function Get-PSImplicitRemotingSession
// index 0 - "-VMId <vm id>" (VMId is used instead of VMName due to its uniqueness) // index 0 - "-VMId <vm id>" (VMId is used instead of VMName due to its uniqueness)
// index 1 - VM credential // index 1 - VM credential
// index 2 - "-ConfigurationName <configuration name>" or empty string
private const string NewVMRunspaceTemplate = @" private const string NewVMRunspaceTemplate = @"
$( $(
& $script:NewPSSession ` & $script:NewPSSession `
{0} ` {0} `
{1} ` {1} `
{2} `
) )
"; ";
// index 0 - "-ContainerId <container id>" (ContainerId is used instead of ContainerName due to its uniqueness) // index 0 - "-ContainerId <container id>" (ContainerId is used instead of ContainerName due to its uniqueness)
// index 1 - "-RunAsAdministrator" or empty string // index 1 - "-RunAsAdministrator" or empty string
// index 2 - "-ConfigurationName <configuration name>" or empty string
private const string NewContainerRunspaceTemplate = @" private const string NewContainerRunspaceTemplate = @"
$( $(
& $script:NewPSSession ` & $script:NewPSSession `
{0} ` {0} `
{1} ` {1} `
{2} `
) )
"; ";
@@ -2530,22 +2534,26 @@ function Get-PSImplicitRemotingSession
VMConnectionInfo vmConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as VMConnectionInfo; VMConnectionInfo vmConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as VMConnectionInfo;
if (vmConnectionInfo != null) if (vmConnectionInfo != null)
{ {
string vmConfigurationName = vmConnectionInfo.ConfigurationName;
return string.Format( return string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
NewVMRunspaceTemplate, NewVMRunspaceTemplate,
/* 0 */ this.GenerateConnectionStringForNewRunspace(), /* 0 */ this.GenerateConnectionStringForNewRunspace(),
/* 1 */ this.GenerateCredentialParameter()); /* 1 */ this.GenerateCredentialParameter(),
/* 2 */ String.IsNullOrEmpty(vmConfigurationName) ? String.Empty : String.Concat("-ConfigurationName ", vmConfigurationName));
} }
else else
{ {
ContainerConnectionInfo containerConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as ContainerConnectionInfo; ContainerConnectionInfo containerConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as ContainerConnectionInfo;
if (containerConnectionInfo != null) if (containerConnectionInfo != null)
{ {
string containerConfigurationName = containerConnectionInfo.ContainerProc.ConfigurationName;
return string.Format( return string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
NewContainerRunspaceTemplate, NewContainerRunspaceTemplate,
/* 0 */ this.GenerateConnectionStringForNewRunspace(), /* 0 */ this.GenerateConnectionStringForNewRunspace(),
/* 1 */ containerConnectionInfo.ContainerProc.RunAsAdmin ? "-RunAsAdministrator" : string.Empty); /* 1 */ containerConnectionInfo.ContainerProc.RunAsAdmin ? "-RunAsAdministrator" : string.Empty,
/* 2 */ String.IsNullOrEmpty(containerConfigurationName) ? String.Empty : String.Concat("-ConfigurationName ", containerConfigurationName));
} }
else else
{ {
@@ -44,5 +44,5 @@
} }
}, },
"compile": [ "../windows-build/gen/COMMANDS_UTILITY/*.cs" ] "compile": [ "../windows-build/gen/Microsoft.PowerShell.Commands.Utility/*.cs" ]
} }
@@ -0,0 +1,16 @@
@{
GUID="CA046F10-CA64-4740-8FF9-2565DBA61A4F"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
AliasesToExport = @()
FunctionsToExport = @()
CmdletsToExport="Get-WinEvent", "Get-Counter", "Import-Counter", "Export-Counter", "New-WinEvent"
NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll"
TypesToProcess="GetEvent.types.ps1xml"
FormatsToProcess="Event.format.ps1xml","Diagnostics.format.ps1xml"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390783'
}
@@ -0,0 +1,33 @@
@{
GUID="1DA87E53-152B-403E-98DC-74D7B4D63D59"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.1.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide",
"Out-File", "Out-Printer", "Out-String",
"Out-GridView", "Get-FormatData", "Export-FormatData", "ConvertFrom-Json", "ConvertTo-Json",
"Invoke-RestMethod", "Invoke-WebRequest", "Register-ObjectEvent", "Register-EngineEvent",
"Wait-Event", "Get-Event", "Remove-Event", "Get-EventSubscriber", "Unregister-Event",
"New-Event", "Add-Member", "Add-Type", "Compare-Object", "ConvertTo-Html", "ConvertFrom-StringData",
"Export-Csv", "Import-Csv", "ConvertTo-Csv", "ConvertFrom-Csv", "Export-Alias", "Invoke-Expression",
"Get-Alias", "Get-Culture", "Get-Date", "Get-Host", "Get-Member", "Get-Random", "Get-UICulture",
"Get-Unique", "Export-PSSession", "Import-PSSession", "Import-Alias", "Import-LocalizedData",
"Select-String", "Measure-Object", "New-Alias", "New-TimeSpan", "Read-Host", "Set-Alias", "Set-Date",
"Start-Sleep", "Tee-Object", "Measure-Command", "Update-List", "Update-TypeData", "Update-FormatData",
"Remove-TypeData", "Get-TypeData", "Write-Host", "Write-Progress", "New-Object", "Select-Object",
"Group-Object", "Sort-Object", "Get-Variable", "New-Variable", "Set-Variable", "Remove-Variable",
"Clear-Variable", "Export-Clixml", "Import-Clixml", "ConvertTo-Xml", "Select-Xml", "Write-Debug",
"Write-Verbose", "Write-Warning", "Write-Error", "Write-Information", "Write-Output", "Set-PSBreakpoint", "Get-PSBreakpoint",
"Remove-PSBreakpoint", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack",
"Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Show-Command", "Unblock-File",
"Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", "Get-RunspaceDebug", "Wait-Debugger",
"ConvertFrom-String", "Convert-String"
FunctionsToExport= "Get-FileHash", "New-TemporaryFile", "New-Guid", "Format-Hex", "Import-PowerShellDataFile",
"ConvertFrom-SddlString"
AliasesToExport= "CFS", "fhx"
NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390787'
}
@@ -239,7 +239,7 @@ namespace Microsoft.PowerShell
else if (cpp.NamedPipeServerMode) else if (cpp.NamedPipeServerMode)
{ {
ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode"); ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode");
System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(); System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(cpp.ConfigurationName);
exitCode = 0; exitCode = 0;
} }
else if (cpp.SocketServerMode) else if (cpp.SocketServerMode)
@@ -14,12 +14,18 @@
"Microsoft.PowerShell.Commands.Utility": "1.0.0-*" "Microsoft.PowerShell.Commands.Utility": "1.0.0-*"
}, },
"content": [
"Modules",
"../Modules",
"powershell.exe"
],
"frameworks": { "frameworks": {
"net451": { "net451": {
} }
}, },
"compile": [ "compile": [
"../windows-build/gen/CONSOLE_HOST/*.cs" "../windows-build/gen/Microsoft.PowerShell.ConsoleHost/*.cs"
] ]
} }
@@ -31,5 +31,5 @@
} }
}, },
"compile": [ "../windows-build/gen/CORECLR_EVENTING/*.cs" ] "compile": [ "../windows-build/gen/Microsoft.PowerShell.CoreCLR.Eventing/*.cs" ]
} }
@@ -0,0 +1,13 @@
@{
GUID="CA046F10-CA64-4740-8FF9-2565DBA61A4F"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
CmdletsToExport="Get-WinEvent", "New-WinEvent"
NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll"
TypesToProcess="..\..\GetEvent.types.ps1xml"
FormatsToProcess="..\..\Event.format.ps1xml"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390783'
}
@@ -1,4 +1,4 @@
namespace Microsoft.PowerShell.Linux.Host namespace Microsoft.PowerShell.Host
{ {
using System; using System;
using System.Globalization; using System.Globalization;
@@ -1,4 +1,4 @@
namespace Microsoft.PowerShell.Linux.Host namespace Microsoft.PowerShell.Host
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -19,6 +19,7 @@
"content": [ "content": [
"Modules", "Modules",
"../Modules",
"*_profile.ps1", "*_profile.ps1",
"*.so", "*.so",
"*.dylib" "*.dylib"
@@ -28,5 +29,15 @@
"netstandardapp1.5": { "netstandardapp1.5": {
"imports": [ "dnxcore50", "portable-net45+win8" ] "imports": [ "dnxcore50", "portable-net45+win8" ]
} }
},
"runtimes": {
"ubuntu.14.04-x64": { },
"centos.7.1-x64": { },
"win7-x64": { },
"win81-x64": { },
"win10-x64": { },
"osx.10.10-x64": { },
"osx.10.11-x64": { }
} }
} }
@@ -10,7 +10,7 @@ using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Microsoft.PowerShell.Linux.Host namespace Microsoft.PowerShell.Host
{ {
// this is all from https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx // this is all from https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx
@@ -1,4 +1,4 @@
namespace Microsoft.PowerShell.Linux.Host namespace Microsoft.PowerShell.Host
{ {
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@@ -1,4 +1,4 @@
namespace Microsoft.PowerShell.Linux.Host namespace Microsoft.PowerShell.Host
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -1,26 +0,0 @@
#!/usr/bin/env bash
# Types files
cp ../monad/monad/miscfiles/types/CoreClr/types.ps1xml .
cp ../monad/monad/miscfiles/types/CoreClr/typesv3.ps1xml .
# Format files
cp ../monad/monad/miscfiles/display/Certificate.format.ps1xml .
cp ../monad/monad/miscfiles/display/Diagnostics.Format.ps1xml Diagnostics.format.ps1xml
cp ../monad/monad/miscfiles/display/DotNetTypes.format.ps1xml .
cp ../monad/monad/miscfiles/display/Event.format.ps1xml .
cp ../monad/monad/miscfiles/display/FileSystem.format.ps1xml .
cp ../monad/monad/miscfiles/display/Help.format.ps1xml .
cp ../monad/monad/miscfiles/display/HelpV3.format.ps1xml .
cp ../monad/monad/miscfiles/display/PowerShellCore.format.ps1xml .
cp ../monad/monad/miscfiles/display/PowerShellTrace.format.ps1xml .
cp ../monad/monad/miscfiles/display/Registry.format.ps1xml .
cp ../monad/monad/miscfiles/display/WSMan.format.ps1xml .
mkdir Modules
cp -r ../monad/monad/miscfiles/modules/Microsoft.PowerShell.Utility Modules
UTILSCLR=Modules/Microsoft.PowerShell.Utility/CoreClr
mv $UTILSCLR/* Modules/Microsoft.PowerShell.Utility && rmdir $UTILSCLR
cp -r ../monad/monad/miscfiles/modules/Microsoft.PowerShell.Security Modules
cp -r ../monad/monad/miscfiles/modules/Microsoft.PowerShell.Management Modules
cp -r ../monad/monad/miscfiles/modules/PSDiagnostics Modules
@@ -23,5 +23,5 @@
} }
}, },
"compile": [ "../windows-build/gen/SECURITY/*.cs" ] "compile": [ "../windows-build/gen/Microsoft.PowerShell.Security/*.cs" ]
} }
Binary file not shown.
Binary file not shown.
+956
View File
@@ -0,0 +1,956 @@
#########################################################################################
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# Appx Provider Module
#
#########################################################################################
$script:ProviderName = "appx"
$script:AppxPackageExtension = ".appx"
$script:AppxManifestFile = "AppxManifest.xml"
$script:Architecture = "Architecture"
$script:ResourceId = "ResourceId"
$script:AppxPackageSources = $null
$script:AppxLocalPath="$env:LOCALAPPDATA\Microsoft\Windows\PowerShell\AppxProvider"
$script:AppxPackageSourcesFilePath = Microsoft.PowerShell.Management\Join-Path -Path $script:AppxLocalPath -ChildPath "AppxPackageSources.xml"
$Script:ResponseUri = "ResponseUri"
$Script:StatusCode = "StatusCode"
# Wildcard pattern matching configuration.
$script:wildcardOptions = [System.Management.Automation.WildcardOptions]::CultureInvariant -bor `
[System.Management.Automation.WildcardOptions]::IgnoreCase
#Localized Data
Microsoft.PowerShell.Utility\Import-LocalizedData LocalizedData -filename AppxProvider.Resource.psd1
#region Appx Provider APIs Implementation
function Get-PackageProviderName
{
return $script:ProviderName
}
function Initialize-Provider{
param(
)
}
function Get-DynamicOptions
{
param
(
[Microsoft.PackageManagement.MetaProvider.PowerShell.OptionCategory]
$category
)
Write-Debug ($LocalizedData.ProviderApiDebugMessage -f ('Get-DynamicOptions'))
switch($category)
{
Install {
Write-Output -InputObject (New-DynamicOption -Category $category -Name Architecture -ExpectedType String -IsRequired $false)
Write-Output -InputObject (New-DynamicOption -Category $category -Name ResourceId -ExpectedType String -IsRequired $false)
}
Package {
Write-Output -InputObject (New-DynamicOption -Category $category -Name Architecture -ExpectedType String -IsRequired $false)
Write-Output -InputObject (New-DynamicOption -Category $category -Name ResourceId -ExpectedType String -IsRequired $false)
}
}
}
function Find-Package
{
[CmdletBinding()]
param
(
[string[]]
$names,
[string]
$requiredVersion,
[string]
$minimumVersion,
[string]
$maximumVersion
)
Write-Debug ($LocalizedData.ProviderApiDebugMessage -f ('Find-Package'))
$ResourceId = $null
$Architecture = $null
$Sources = @()
$streamedResults = @()
$namesParameterEmpty = (-not $names) -or (($names.Count -eq 1) -and ($names[0] -eq ''))
Set-PackageSourcesVariable
if($RequiredVersion -and $MinimumVersion)
{
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $LocalizedData.VersionRangeAndRequiredVersionCannotBeSpecifiedTogether `
-ErrorId "VersionRangeAndRequiredVersionCannotBeSpecifiedTogether" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument
}
if($RequiredVersion -or $MinimumVersion)
{
if(-not $names -or $names.Count -ne 1 -or (Test-WildcardPattern -Name $names[0]))
{
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $LocalizedData.VersionParametersAreAllowedOnlyWithSinglePackage `
-ErrorId "VersionParametersAreAllowedOnlyWithSinglePackage" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument
}
}
$options = $request.Options
if($options)
{
foreach( $o in $options.Keys )
{
Write-Debug ( "OPTION: {0} => {1}" -f ($o, $options[$o]) )
}
if($options.ContainsKey('Source'))
{
$SourceNames = $($options['Source'])
Write-Verbose ($LocalizedData.SpecifiedSourceName -f ($SourceNames))
foreach($sourceName in $SourceNames)
{
if($script:AppxPackageSources.Contains($sourceName))
{
$Sources += $script:AppxPackageSources[$sourceName]
}
else
{
$sourceByLocation = Get-SourceName -Location $sourceName
if ($sourceByLocation -ne $null)
{
$Sources += $script:AppxPackageSources[$sourceByLocation]
}
else
{
$message = $LocalizedData.PackageSourceNotFound -f ($sourceName)
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "PackageSourceNotFound" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument `
-ExceptionObject $sourceName
}
}
}
}
else
{
Write-Verbose $LocalizedData.NoSourceNameIsSpecified
$script:AppxPackageSources.Values | Microsoft.PowerShell.Core\ForEach-Object { $Sources += $_ }
}
if($options.ContainsKey($script:Architecture))
{
$Architecture = $options[$script:Architecture]
}
if($options.ContainsKey($script:ResourceId))
{
$ResourceId = $options[$script:ResourceId]
}
}
foreach($source in $Sources)
{
$location = $source.SourceLocation
if($request.IsCanceled)
{
return
}
if(-not(Test-Path $location))
{
$message = $LocalizedData.PathNotFound -f ($Location)
Write-Verbose $message
continue
}
$packages = Get-AppxPackagesFromPath -path $location
foreach($pkg in $packages)
{
if($request.IsCanceled)
{
return
}
$pkgManifest = Get-PackageManfiestData -PackageFullPath $pkg.FullName
if(-not $pkgManifest)
{
continue
}
# $pkgManifest.Name has to match any of the supplied names, using PowerShell wildcards
if(-not($namesParameterEmpty))
{
if(-not(($names | Microsoft.PowerShell.Core\ForEach-Object { if ($pkgManifest.Name -like $_){return $true; break} } -End {return $false})))
{
continue
}
}
# Version
if($RequiredVersion)
{
if($RequiredVersion -ne $pkgManifest.Version)
{
continue
}
}
else
{
if(-not((-not $MinimumVersion -or ($MinimumVersion -le $pkgManifest.Version)) -and
(-not $MaximumVersion -or ($MaximumVersion -ge $pkgManifest.Version))))
{
continue
}
}
if($Architecture)
{
$wildcardPattern = New-Object System.Management.Automation.WildcardPattern $Architecture, $script:wildcardOptions
if(-not($wildcardPattern.IsMatch($pkgManifest.Architecture)))
{
continue
}
}
if($ResourceId)
{
$wildcardPattern = New-Object System.Management.Automation.WildcardPattern $ResourceId, $script:wildcardOptions
if(-not($wildcardPattern.IsMatch($pkgManifest.ResourceId)))
{
continue
}
}
$sid = New-SoftwareIdentityFromPackage -Package $pkgManifest -Source $source.Name
$fastPackageReference = $sid.fastPackageReference
if($streamedResults -notcontains $fastPackageReference)
{
$streamedResults += $fastPackageReference
Write-Output -InputObject $sid
}
}
}
}
function Get-InstalledPackage
{
[CmdletBinding()]
param
(
[Parameter()]
[string]
$Name,
[Parameter()]
[string]
$RequiredVersion,
[Parameter()]
[string]
$MinimumVersion,
[Parameter()]
[string]
$MaximumVersion
)
Write-Debug -Message ($LocalizedData.ProviderApiDebugMessage -f ('Get-InstalledPackage'))
$Architecture = $null
$ResourceId = $null
$options = $request.Options
if($options)
{
if($options.ContainsKey($script:Architecture))
{
$Architecture = $options[$script:Architecture]
}
if($options.ContainsKey($script:ResourceId))
{
$ResourceId = $options[$script:ResourceId]
}
}
$params = @{}
if($Name)
{
$params.Add("Name", $Name)
}
$packages = Appx\Get-AppxPackage @params
foreach($package in $packages)
{
if($RequiredVersion)
{
if($RequiredVersion -ne $package.Version)
{
continue
}
}
else
{
if(-not((-not $MinimumVersion -or ($MinimumVersion -le $package.Version)) -and
(-not $MaximumVersion -or ($MaximumVersion -ge $package.Version))))
{
continue
}
}
if($Architecture)
{
$wildcardPattern = New-Object System.Management.Automation.WildcardPattern $Architecture, $script:wildcardOptions
if(-not($wildcardPattern.IsMatch($package.Architecture)))
{
continue
}
}
if($ResourceId)
{
$wildcardPattern = New-Object System.Management.Automation.WildcardPattern $ResourceId,$script:wildcardOptions
if(-not($wildcardPattern.IsMatch($package.ResourceId)))
{
continue
}
}
$sid = New-SoftwareIdentityFromPackage -Package $package
write-Output $sid
}
}
function Install-Package
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$fastPackageReference
)
Write-Debug -Message ($LocalizedData.ProviderApiDebugMessage -f ('Install-Package'))
Write-Debug -Message ($LocalizedData.FastPackageReference -f $fastPackageReference)
Appx\Add-AppxPackage -Path $fastPackageReference
}
function UnInstall-Package
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$fastPackageReference
)
Write-Debug -Message ($LocalizedData.ProviderApiDebugMessage -f ('Uninstall-Package'))
Write-Debug -Message ($LocalizedData.FastPackageReference -f $fastPackageReference)
Appx\Remove-AppxPackage -Package $fastPackageReference
}
function Add-PackageSource
{
[CmdletBinding()]
param
(
[string]
$Name,
[string]
$Location,
[bool]
$Trusted
)
Write-Debug ($LocalizedData.ProviderApiDebugMessage -f ('Add-PackageSource'))
Set-PackageSourcesVariable -Force
if(-not (Microsoft.PowerShell.Management\Test-Path $Location) -and
-not (Test-WebUri -uri $Location))
{
$LocationUri = [Uri]$Location
if($LocationUri.Scheme -eq 'file')
{
$message = $LocalizedData.PathNotFound -f ($Location)
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "PathNotFound" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument `
-ExceptionObject $Location
}
else
{
$message = $LocalizedData.InvalidWebUri -f ($Location, "Location")
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "InvalidWebUri" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument `
-ExceptionObject $Location
}
}
if(Test-WildcardPattern $Name)
{
$message = $LocalizedData.PackageSourceNameContainsWildCards -f ($Name)
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "PackageSourceNameContainsWildCards" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument `
-ExceptionObject $Name
}
$LocationString = Get-ValidPackageLocation -LocationString $Location -ParameterName "Location"
# Check if Location is already registered with another Name
$existingSourceName = Get-SourceName -Location $LocationString
if($existingSourceName -and
($Name -ne $existingSourceName))
{
$message = $LocalizedData.PackageSourceAlreadyRegistered -f ($existingSourceName, $Location, $Name)
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "PackageSourceAlreadyRegistered" `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument
}
# Check if Name is already registered
if($script:AppxPackageSources.Contains($Name))
{
$currentSourceObject = $script:AppxPackageSources[$Name]
$null = $script:AppxPackageSources.Remove($Name)
}
# Add new package source
$packageSource = Microsoft.PowerShell.Utility\New-Object PSCustomObject -Property ([ordered]@{
Name = $Name
SourceLocation = $LocationString
Trusted=$Trusted
Registered= $true
})
$script:AppxPackageSources.Add($Name, $packageSource)
$message = $LocalizedData.SourceRegistered -f ($Name, $LocationString)
Write-Verbose $message
# Persist the package sources
Save-PackageSources
# return the package source object.
Write-Output -InputObject (New-PackageSourceFromSource -Source $packageSource)
}
function Resolve-PackageSource
{
Write-Debug ($LocalizedData.ProviderApiDebugMessage -f ('Resolve-PackageSource'))
Set-PackageSourcesVariable
$SourceName = $request.PackageSources
if(-not $SourceName)
{
$SourceName = "*"
}
foreach($src in $SourceName)
{
if($request.IsCanceled)
{
return
}
$wildcardPattern = New-Object System.Management.Automation.WildcardPattern $src,$script:wildcardOptions
$sourceFound = $false
$script:AppxPackageSources.GetEnumerator() |
Microsoft.PowerShell.Core\Where-Object {$wildcardPattern.IsMatch($_.Key)} |
Microsoft.PowerShell.Core\ForEach-Object {
$source = $script:AppxPackageSources[$_.Key]
$packageSource = New-PackageSourceFromSource -Source $source
Write-Output -InputObject $packageSource
$sourceFound = $true
}
if(-not $sourceFound)
{
$sourceName = Get-SourceName -Location $src
if($sourceName)
{
$source = $script:AppxPackageSources[$sourceName]
$packageSource = New-PackageSourceFromSource -Source $source
Write-Output -InputObject $packageSource
}
elseif( -not (Test-WildcardPattern $src))
{
$message = $LocalizedData.PackageSourceNotFound -f ($src)
Write-Error -Message $message -ErrorId "PackageSourceNotFound" -Category InvalidOperation -TargetObject $src
}
}
}
}
function Remove-PackageSource
{
param
(
[string]
$Name
)
Write-Debug ($LocalizedData.ProviderApiDebugMessage -f ('Remove-PackageSource'))
Set-PackageSourcesVariable -Force
$SourcesToBeRemoved = @()
foreach ($sourceName in $Name)
{
if($request.IsCanceled)
{
return
}
# Check if $Name contains any wildcards
if(Test-WildcardPattern $sourceName)
{
$message = $LocalizedData.PackageSourceNameContainsWildCards -f ($sourceName)
Write-Error -Message $message -ErrorId "PackageSourceNameContainsWildCards" -Category InvalidOperation -TargetObject $sourceName
continue
}
# Check if the specified package source name is in the registered package sources
if(-not $script:AppxPackageSources.Contains($sourceName))
{
$message = $LocalizedData.PackageSourceNotFound -f ($sourceName)
Write-Error -Message $message -ErrorId "PackageSourceNotFound" -Category InvalidOperation -TargetObject $sourceName
continue
}
$SourcesToBeRemoved += $sourceName
$message = $LocalizedData.PackageSourceUnregistered -f ($sourceName)
Write-Verbose $message
}
# Remove the SourcesToBeRemoved
$SourcesToBeRemoved | Microsoft.PowerShell.Core\ForEach-Object { $null = $script:AppxPackageSources.Remove($_) }
# Persist the package sources
Save-PackageSources
}
#endregion
#region Common functions
function Get-AppxPackagesFromPath
{
param
(
[Parameter(Mandatory=$true)]
$Path
)
$filterAppxPackages = "*"+$script:AppxPackageExtension
$packages = Get-ChildItem -path $Path -filter $filterAppxPackages
return $packages
}
function Get-PackageManfiestData
{
param
(
[Parameter(Mandatory=$true)]
$PackageFullPath
)
$guid = [System.Guid]::NewGuid().toString()
try
{
[System.IO.Compression.ZipFile]::ExtractToDirectory($PackageFullPath, "$env:TEMP\$guid")
}
catch
{
Write-Verbose( $LocalizedData.MetaDataExtractionFailed -f ($PackageFullPath) )
return $null
}
[xml] $packageManifest = Get-Content "$env:TEMP\$guid\$script:AppxManifestFile" -ErrorAction SilentlyContinue
if($packageManifest)
{
$Identity = $packageManifest.Package.Identity
$manifestData = new-object psObject -Property @{Name=$Identity.Name; Architecture=$Identity.ProcessorArchitecture; Publisher=$Identity.Publisher; Version=$Identity.Version; ResourceId=$Identity.resourceId; PackageFullName=$PackageFullPath}
Remove-Item -Path "$env:TEMP\$guid" -Recurse -Force -ErrorAction SilentlyContinue
return $manifestData
}
else
{
Write-Verbose ($LocalizedData.MetaDataExtractionFailed -f ($PackageFullPath) )
}
return $null
}
function New-FastPackageReference
{
param
(
[Parameter(Mandatory=$true)]
[string]
$PackageFullName
)
return "$PackageFullName"
}
function New-SoftwareIdentityFromPackage
{
param
(
[Parameter(Mandatory=$true)]
$Package,
[string]
$Source
)
$fastPackageReference = New-FastPackageReference -PackageFullName $Package.PackageFullName
if(-not($Source))
{
$Source = $Package.Publisher
}
$details = @{
Publisher = $Package.Publisher
Architecture = $Package.Architecture
ResourceId = $Package.ResourceId
PackageFullName = $Package.PackageFullName
}
$params = @{
FastPackageReference = $fastPackageReference;
Name = $Package.Name;
Version = $Package.Version;
versionScheme = "MultiPartNumeric";
Source = $source;
Details = $details;
}
$sid = New-SoftwareIdentity @params
return $sid
}
function Test-WebUri
{
[CmdletBinding()]
[OutputType([bool])]
Param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[Uri]
$uri
)
return ($uri.AbsoluteURI -ne $null) -and ($uri.Scheme -match '[http|https]')
}
function Test-WildcardPattern
{
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
$Name
)
return [System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Name)
}
function DeSerialize-PSObject
{
[CmdletBinding(PositionalBinding=$false)]
Param
(
[Parameter(Mandatory=$true)]
$Path
)
$filecontent = Microsoft.PowerShell.Management\Get-Content -Path $Path
[System.Management.Automation.PSSerializer]::Deserialize($filecontent)
}
function Get-SourceName
{
[CmdletBinding()]
[OutputType("string")]
Param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$Location
)
Set-PackageSourcesVariable
foreach($source in $script:AppxPackageSources.Values)
{
if($source.SourceLocation -eq $Location)
{
return $source.Name
}
}
}
function WebRequestApisAvailable
{
$webRequestApiAvailable = $false
try
{
[System.Net.WebRequest]
$webRequestApiAvailable = $true
}
catch
{
}
return $webRequestApiAvailable
}
function Ping-Endpoint
{
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string[]]
$Endpoint
)
$results = @{}
if(WebRequestApisAvailable)
{
$iss = [System.Management.Automation.Runspaces.InitialSessionState]::Create()
$iss.types.clear()
$iss.formats.clear()
$iss.LanguageMode = "FullLanguage"
$WebRequestcmd = @'
try
{{
$request = [System.Net.WebRequest]::Create("{0}")
$request.Method = 'GET'
$request.Timeout = 30000
$response = [System.Net.HttpWebResponse]$request.GetResponse()
$response
$response.Close()
}}
catch [System.Net.WebException]
{{
"Error:System.Net.WebException"
}}
'@ -f $EndPoint
$ps = [powershell]::Create($iss).AddScript($WebRequestcmd)
$response = $ps.Invoke()
$ps.dispose()
if ($response -ne "Error:System.Net.WebException")
{
$results.Add($Script:ResponseUri,$response.ResponseUri.ToString())
$results.Add($Script:StatusCode,$response.StatusCode.value__)
}
}
else
{
$response = $null
try
{
$httpClient = New-Object 'System.Net.Http.HttpClient'
$response = $httpclient.GetAsync($endpoint)
}
catch
{
}
if ($response -ne $null -and $response.result -ne $null)
{
$results.Add($Script:ResponseUri,$response.Result.RequestMessage.RequestUri.AbsoluteUri.ToString())
$results.Add($Script:StatusCode,$response.result.StatusCode.value__)
}
}
return $results
}
function Get-ValidPackageLocation
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$LocationString,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$ParameterName
)
# Get the actual Uri from the Location
if(-not (Microsoft.PowerShell.Management\Test-Path $LocationString))
{
$results = Ping-Endpoint -Endpoint $LocationString
if ($results.ContainsKey("Exception"))
{
$Exception = $results["Exception"]
if($Exception)
{
$message = $LocalizedData.InvalidWebUri -f ($LocationString, $ParameterName)
ThrowError -ExceptionName "System.ArgumentException" `
-ExceptionMessage $message `
-ErrorId "InvalidWebUri" `
-ExceptionObject $Exception `
-CallerPSCmdlet $PSCmdlet `
-ErrorCategory InvalidArgument
}
}
if ($results.ContainsKey("ResponseUri"))
{
$LocationString = $results["ResponseUri"]
}
}
return $LocationString
}
function Set-PackageSourcesVariable
{
param([switch]$Force)
if(-not $script:AppxPackageSources -or $Force)
{
if(Microsoft.PowerShell.Management\Test-Path $script:AppxPackageSourcesFilePath)
{
$script:AppxPackageSources = DeSerialize-PSObject -Path $script:AppxPackageSourcesFilePath
}
else
{
$script:AppxPackageSources = [ordered]@{}
}
}
}
function Save-PackageSources
{
if($script:AppxPackageSources)
{
if(-not (Microsoft.PowerShell.Management\Test-Path $script:AppxLocalPath))
{
$null = Microsoft.PowerShell.Management\New-Item -Path $script:AppxLocalPath `
-ItemType Directory -Force `
-ErrorAction SilentlyContinue `
-WarningAction SilentlyContinue `
-Confirm:$false -WhatIf:$false
}
Microsoft.PowerShell.Utility\Out-File -FilePath $script:AppxPackageSourcesFilePath -Force -InputObject ([System.Management.Automation.PSSerializer]::Serialize($script:AppxPackageSources))
}
}
function New-PackageSourceFromSource
{
param
(
[Parameter(Mandatory)]
$Source
)
# create a new package source
$src = New-PackageSource -Name $Source.Name `
-Location $Source.SourceLocation `
-Trusted $Source.Trusted `
-Registered $Source.Registered `
Write-Verbose ( $LocalizedData.PackageSourceDetails -f ($src.Name, $src.Location, $src.IsTrusted, $src.IsRegistered) )
# return the package source object.
Write-Output -InputObject $src
}
#endregion
# Utility to throw an errorrecord
function ThrowError
{
param
(
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.PSCmdlet]
$CallerPSCmdlet,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$ExceptionName,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$ExceptionMessage,
[System.Object]
$ExceptionObject,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$ErrorId,
[parameter(Mandatory = $true)]
[ValidateNotNull()]
[System.Management.Automation.ErrorCategory]
$ErrorCategory
)
$exception = New-Object $ExceptionName $ExceptionMessage;
$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $ErrorCategory, $ExceptionObject
$CallerPSCmdlet.ThrowTerminatingError($errorRecord)
}
#endregion
Export-ModuleMember -Function Find-Package, `
Install-Package, `
Uninstall-Package, `
Get-InstalledPackage, `
Remove-PackageSource, `
Resolve-PackageSource, `
Add-PackageSource, `
Get-DynamicOptions, `
Initialize-Provider, `
Get-PackageProviderName
@@ -0,0 +1,12 @@
@{
GUID="eb74e8da-9ae2-482a-a648-e96550fb8733"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="1.0.0.0"
FunctionsToExport = @('Compress-Archive', 'Expand-Archive')
CmdletsToExport = @()
AliasesToExport = @()
NestedModules="Microsoft.PowerShell.Archive.psm1"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?LinkId=393254'
}
@@ -0,0 +1,14 @@
@{
GUID="56D66100-99A0-4FFC-A12D-EEE9A6718AEF"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
AliasesToExport = @()
FunctionsToExport = @()
CmdletsToExport="Start-Transcript", "Stop-Transcript"
NestedModules="Microsoft.PowerShell.ConsoleHost.dll"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390784'
}
@@ -0,0 +1,99 @@
@{
GUID="EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.1.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
NestedModules="Microsoft.PowerShell.Commands.Management.dll"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390785'
AliasesToExport = @("gcb", "scb")
FunctionsToExport = @()
CmdletsToExport=@("Add-Content",
"Clear-Content",
"Clear-ItemProperty",
"Join-Path",
"Convert-Path",
"Copy-ItemProperty",
"Get-EventLog",
"Clear-EventLog",
"Write-EventLog",
"Limit-EventLog",
"Show-EventLog",
"New-EventLog",
"Remove-EventLog",
"Get-ChildItem",
"Get-Content",
"Get-ItemProperty",
"Get-ItemPropertyValue",
"Get-WmiObject",
"Invoke-WmiMethod",
"Move-ItemProperty",
"Get-Location",
"Set-Location",
"Push-Location",
"Pop-Location",
"New-PSDrive",
"Remove-PSDrive",
"Get-PSDrive",
"Get-Item",
"New-Item",
"Set-Item",
"Remove-Item",
"Move-Item",
"Rename-Item",
"Copy-Item",
"Clear-Item",
"Invoke-Item",
"Get-PSProvider",
"New-ItemProperty",
"Split-Path",
"Test-Path",
"Get-Process",
"Stop-Process",
"Wait-Process",
"Debug-Process",
"Start-Process",
"Remove-ItemProperty",
"Remove-WmiObject",
"Rename-ItemProperty",
"Register-WmiEvent",
"Resolve-Path",
"Get-Service",
"Stop-Service",
"Start-Service",
"Suspend-Service",
"Resume-Service",
"Restart-Service",
"Set-Service",
"New-Service",
"Set-Content",
"Set-ItemProperty",
"Set-WmiInstance",
"Get-Transaction",
"Start-Transaction",
"Complete-Transaction",
"Undo-Transaction",
"Use-Transaction",
"New-WebServiceProxy",
"Get-HotFix",
"Test-Connection",
"Enable-ComputerRestore",
"Disable-ComputerRestore",
"Checkpoint-Computer",
"Get-ComputerRestorePoint",
"Restart-Computer",
"Stop-Computer",
"Restore-Computer",
"Add-Computer",
"Remove-Computer",
"Test-ComputerSecureChannel",
"Reset-ComputerMachinePassword",
"Rename-Computer",
"Get-ControlPanelItem",
"Show-ControlPanelItem",
"Clear-Recyclebin",
"Get-Clipboard",
"Set-Clipboard")
}
@@ -0,0 +1,14 @@
@{
GUID="A94C8C7E-9810-47C0-B8AF-65089C13A35A"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
AliasesToExport = @()
FunctionsToExport = @()
CmdletsToExport="Get-Acl", "Set-Acl", "Get-PfxCertificate", "Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "Get-AuthenticodeSignature", "Set-AuthenticodeSignature", "ConvertFrom-SecureString", "ConvertTo-SecureString", "Get-CmsMessage", "Unprotect-CmsMessage", "Protect-CmsMessage" , "New-FileCatalog" , "Test-FileCatalog"
NestedModules="Microsoft.PowerShell.Security.dll"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390786'
}
@@ -0,0 +1,709 @@
function Get-FileHash
{
[CmdletBinding(DefaultParameterSetName = "Path", HelpURI = "http://go.microsoft.com/fwlink/?LinkId=517145")]
param(
[Parameter(Mandatory, ParameterSetName="Path", Position = 0)]
[System.String[]]
$Path,
[Parameter(Mandatory, ParameterSetName="LiteralPath", ValueFromPipelineByPropertyName = $true)]
[Alias("PSPath")]
[System.String[]]
$LiteralPath,
[Parameter(Mandatory, ParameterSetName="Stream")]
[System.IO.Stream]
$InputStream,
[ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MACTripleDES", "MD5", "RIPEMD160")]
[System.String]
$Algorithm="SHA256"
)
begin
{
# Construct the strongly-typed crypto object
# First see if it has a FIPS algorithm
$hasherType = "System.Security.Cryptography.${Algorithm}CryptoServiceProvider" -as [Type]
if ($hasherType)
{
$hasher = $hasherType::New()
}
else
{
# Check if the type is supported in the current system
$algorithmType = "System.Security.Cryptography.${Algorithm}" -as [Type]
if ($algorithmType)
{
if ($Algorithm -eq "MACTripleDES")
{
$hasher = $algorithmType::New()
}
else
{
$hasher = $algorithmType::Create()
}
}
else
{
$errorId = "AlgorithmTypeNotSupported"
$errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument
$errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::AlgorithmTypeNotSupported -f $Algorithm
$exception = [System.InvalidOperationException]::New($errorMessage)
$errorRecord = [System.Management.Automation.ErrorRecord]::New($exception, $errorId, $errorCategory, $null)
$PSCmdlet.ThrowTerminatingError($errorRecord)
}
}
function GetStreamHash
{
param(
[System.IO.Stream]
$InputStream,
[System.String]
$RelatedPath,
[System.Security.Cryptography.HashAlgorithm]
$Hasher)
# Compute file-hash using the crypto object
[Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)
[string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''
if ($RelatedPath -eq $null)
{
$retVal = [PSCustomObject] @{
Algorithm = $Algorithm.ToUpperInvariant()
Hash = $hash
}
}
else
{
$retVal = [PSCustomObject] @{
Algorithm = $Algorithm.ToUpperInvariant()
Hash = $hash
Path = $RelatedPath
}
}
$retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
$retVal
}
}
process
{
if($PSCmdlet.ParameterSetName -eq "Stream")
{
GetStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher
}
else
{
$pathsToProcess = @()
if($PSCmdlet.ParameterSetName -eq "LiteralPath")
{
$pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object ProviderPath
}
if($PSCmdlet.ParameterSetName -eq "Path")
{
$pathsToProcess += Resolve-Path $Path | Foreach-Object ProviderPath
}
foreach($filePath in $pathsToProcess)
{
if(Test-Path -LiteralPath $filePath -PathType Container)
{
continue
}
try
{
# Read the file specified in $FilePath as a Byte array
[system.io.stream]$stream = [system.io.file]::OpenRead($filePath)
GetStreamHash -InputStream $stream -RelatedPath $filePath -Hasher $hasher
}
catch [Exception]
{
$errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::FileReadError -f $FilePath, $_
Write-Error -Message $errorMessage -Category ReadError -ErrorId "FileReadError" -TargetObject $FilePath
return
}
finally
{
if($stream)
{
$stream.Dispose()
}
}
}
}
}
}
<# This cmdlet is used to create a new temporary file in $env:temp #>
function New-TemporaryFile
{
[CmdletBinding(
HelpURI='http://go.microsoft.com/fwlink/?LinkId=526726',
SupportsShouldProcess=$true)]
[OutputType([System.IO.FileInfo])]
Param()
Begin
{
try
{
if($PSCmdlet.ShouldProcess($env:TEMP))
{
$tempFilePath = [System.IO.Path]::GetTempFileName()
}
}
catch
{
$errorRecord = [System.Management.Automation.ErrorRecord]::new($_.Exception,"NewTemporaryFileWriteError", "WriteError", $env:TEMP)
Write-Error -ErrorRecord $errorRecord
return
}
if($tempFilePath)
{
Get-Item $tempFilePath
}
}
}
<# This cmdlet is used to generate a new guid #>
function New-Guid
{
[CmdletBinding(HelpURI='http://go.microsoft.com/fwlink/?LinkId=526920')]
[OutputType([System.Guid])]
Param()
Begin
{
[Guid]::NewGuid()
}
}
<############################################################################################
# Format-Hex cmdlet helps in displaying the Hexadecimal equivalent of the input data.
############################################################################################>
function Format-Hex
{
[CmdletBinding(
DefaultParameterSetName="Path",
HelpUri="http://go.microsoft.com/fwlink/?LinkId=526919")]
[Alias("fhx")]
[OutputType("Microsoft.PowerShell.Commands.ByteCollection")]
param
(
[Parameter (Mandatory=$true, Position=0, ParameterSetName="Path")]
[ValidateNotNullOrEmpty()]
[string[]] $Path,
[Parameter (Mandatory=$true, ParameterSetName="LiteralPath")]
[ValidateNotNullOrEmpty()]
[Alias("PSPath")]
[string[]] $LiteralPath,
[Parameter(Mandatory=$true, ParameterSetName="ByInputObject", ValueFromPipeline=$true)]
[Object] $InputObject,
[Parameter (ParameterSetName="ByInputObject")]
[ValidateSet("Ascii", "UTF32", "UTF7", "UTF8", "BigEndianUnicode", "Unicode")]
[string] $Encoding = "Ascii",
[Parameter(ParameterSetName="ByInputObject")]
[switch]$Raw
)
begin
{
$bufferSize = 16
$inputStreamArray = [System.Collections.ArrayList]::New()
<############################################################################################
# The ConvertToHexadecimalHelper is a helper method used to fetch unicode bytes from the
# input data and display the hexadecimial representaion of the of the input data in bytes.
############################################################################################>
function ConvertToHexadecimalHelper
{
param
(
[Byte[]] $inputBytes,
[string] $path,
[Uint32] $offset
)
# This section is used to display the hexadecimal
# representaion of the of the input data in bytes.
if($inputBytes -ne $null)
{
$byteCollectionObject = [Microsoft.PowerShell.Commands.ByteCollection]::new($offset, $inputBytes, $path)
Write-Output -InputObject $byteCollectionObject
}
}
<############################################################################################
# The ProcessFileContent is a helper method used to fetch file contents in blocks and
# process it to support displaying hexadecimal formating of the fetched content.
############################################################################################>
function ProcessFileContent
{
param
(
[string] $filePath,
[boolean] $isLiteralPath
)
if($isLiteralPath)
{
$resolvedPaths = Resolve-Path -LiteralPath $filePath
}
else
{
$resolvedPaths = Resolve-Path -Path $filePath
}
# If Path resolution has failed then a corresponding non-terminating error is
# written to the pipeline. We continue processing any remaining files.
if($resolvedPaths -eq $null)
{
return
}
if($resolvedPaths.Count -gt 1)
{
# write a non-terminating error message indicating that path specified is resolving to multiple file system paths.
$errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::FormatHexResolvePathError -f $filePath
Write-Error -Message $errorMessage -Category ([System.Management.Automation.ErrorCategory]::InvalidData) -ErrorId "FormatHexResolvePathError"
}
$targetFilePath = $resolvedPaths.ProviderPath
if($targetFilePath -ne $null)
{
$buffer = [byte[]]::new($bufferSize)
try
{
try
{
$currentFileStream = [System.IO.File]::Open($targetFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
}
catch
{
# Failed to access the file. Write a non terminating error to the pipeline
# and move on with the remaining files.
$exception = $_.Exception
if($null -ne $_.Exception -and
$null -ne $_.Exception.InnerException)
{
$exception = $_.Exception.InnerException
}
$errorRecord = [System.Management.Automation.ErrorRecord]::new($exception,"FormatHexFileAccessError", ([System.Management.Automation.ErrorCategory]::ReadError), $targetFilePath)
$PSCmdlet.WriteError($errorRecord)
}
if($null -ne $currentFileStream)
{
$srcStream = [System.IO.BinaryReader]::new($currentFileStream)
$displayHeader = $true
$offset = 0
$blockCounter = 0
while($numberOfBytesRead = $srcStream.Read($buffer, 0, $bufferSize))
{
# send only the bytes that have been read
# if we send the whole buffer, we'll have extraneous bytes
# at the end of an incomplete group of 16 bytes
if ( $numberOfBytesRead -eq $bufferSize )
{
# under some circumstances if we don't copy the buffer
# and the results are stored to a variable, the results are not
# correct and one object replicated in all the output objects
ConvertToHexadecimalHelper ($buffer.Clone()) $targetFilePath $offset
}
else
{
# handle the case of the partial (and probably last) buffer
$bytesReadBuffer = [byte[]]::New($numberOfBytesRead)
[Array]::Copy($buffer,0, $bytesReadBuffer,0,$numberOfBytesRead)
ConvertToHexadecimalHelper $bytesReadBuffer $targetFilePath $offset
}
$displayHeader = $false
$blockCounter++;
# Updating the offset value.
$offset = $blockCounter*0x10
}
}
}
finally
{
If($null -ne $currentFileStream)
{
$currentFileStream.Dispose()
}
If($null -ne $srcStream)
{
$srcStream.Dispose()
}
}
}
}
}
process
{
switch($PSCmdlet.ParameterSetName)
{
"Path"
{
ProcessFileContent $Path $false
}
"LiteralPath"
{
ProcessFileContent $LiteralPath $true
}
"ByInputObject"
{
# If it's an actual byte array, then we directly use it for hexadecimal formatting.
if($InputObject -is [Byte[]])
{
ConvertToHexadecimalHelper $InputObject $null
return
}
# if it's a single byte, we'll assume streaming
elseif($InputObject -is [byte])
{
$null = $inputStreamArray.Add($InputObject)
}
# If the input data is of string type then directly get bytes out of it.
elseif($InputObject -is [string])
{
# The ValidateSet arribute on the Encoding paramter makes sure that only
# valid values (supported on all paltforms where Format-Hex is avaliable)
# are allowed through user input.
$inputBytes = [Text.Encoding]::$Encoding.GetBytes($InputObject)
ConvertToHexadecimalHelper $inputBytes $null
return
}
elseif($InputObject -is [System.IO.FileSystemInfo])
{
# If file path is provided as an input, use the file contents to show the hexadecimal format.
$filePath = ([System.IO.FileSystemInfo]$InputObject).FullName
ProcessFileContent $filePath $false
return
}
elseif($InputObject -is [int64])
{
$inputBytes = [BitConverter]::GetBytes($InputObject)
$null = $inputStreamArray.AddRange($inputBytes)
}
elseif($InputObject -is [int64[]])
{
foreach($i64 in $InputObject)
{
$inputBytes = [BitConverter]::GetBytes($i64)
$null = $inputStreamArray.AddRange($inputBytes)
}
}
elseif($InputObject -is [int])
{
# If we get what appears as ints, it may not be what the user really wants.
# for example, if the user types a small set of numbers just to get their
# character representations, as follows:
#
# 170..180 | format-hex
# Path:
# 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
#00000000 AA AB AC AD AE AF B0 B1 B2 B3 B4 ª«¬­®¯°±²³´
#
# any integer padding is likely to be more confusing than this
# fairly compact representation.
#
# However, some might like to see the results with the raw data,
# -Raw exists to provide that behavior:
# PS# 170..180 | format-hex -Raw
#
# Path:
#
# 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
#
# 00000000 AA 00 00 00 AB 00 00 00 AC 00 00 00 AD 00 00 00 ª...«...¬...­...
# 00000010 AE 00 00 00 AF 00 00 00 B0 00 00 00 B1 00 00 00 ®...¯...°...±...
# 00000020 B2 00 00 00 B3 00 00 00 B4 00 00 00 ²...³...´...
#
# this provides a representation of the piped numbers which includes all
# of the bytes which are in an int32
if ( $Raw )
{
$inputBytes = [BitConverter]::GetBytes($InputObject)
$null = $inputStreamArray.AddRange($inputBytes)
}
else
{
# first determine whether we can represent this as a byte
$possibleByte = $InputObject -as [byte]
# first determine whether we can represent this as a int16
$possibleInt16 = $InputObject -as [int16]
if ( $possibleByte -ne $null )
{
$null = $inputStreamArray.Add($possibleByte)
}
elseif ( $possibleint16 -ne $null )
{
$inputBytes = [BitConverter]::GetBytes($possibleInt16)
$null = $inputStreamArray.AddRange($inputBytes)
}
else
{
# now int
$inputBytes = [BitConverter]::GetBytes($InputObject)
$null = $inputStreamArray.AddRange($inputBytes)
}
}
}
else
{
# Otherwise, write a non-terminating error message indicating that input object type is not supported.
$errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::FormatHexTypeNotSupported -f $InputObject.GetType()
Write-Error -Message $errorMessage -Category ([System.Management.Automation.ErrorCategory]::ParserError) -ErrorId "FormatHexFailureTypeNotSupported"
}
# Handle streaming case here
# during this process we may not have enough characters to create a ByteCollection
# if we do, create as many ByteCollections as necessary, each being 16 bytes in length
if ( $inputStreamArray.Count -ge $bufferSize )
{
$rowCount = [math]::Floor($inputStreamArray.Count/$bufferSize)
$arrayLength = $bufferSize * $rowCount
for($i = 0; $i -lt $rowCount; $i++)
{
$rowOffset = $i * $bufferSize
ConvertToHexadecimalHelper -inputBytes $inputStreamArray.GetRange($rowOffset, $bufferSize) -path ' ' -offset $offset
$offset += $bufferSize
}
# We use RemoveRange because of the pathological case of having
# streamed combination of bytes, int16, int32, int64 which are greater
# than 16 bytes. Consider the case:
# $i = [int16]::MaxValue + 3
# $i64=[int64]::MaxValue -5
# .{ $i;$i;$i;$i64 } | format-hex
# which create an arraylist 20 bytes
# we need to remove only the bytes from the array which we emitted
$inputStreamArray.RemoveRange(0,$arrayLength)
}
}
}
}
end
{
# now manage any left over bytes in the $inputStreamArray
if ( $PSCmdlet.ParameterSetName -eq "ByInputObject" )
{
ConvertToHexadecimalHelper $inputStreamArray $null -path ' ' -offset $offset
}
}
}
## Imports a PowerShell Data File - a PowerShell hashtable defined in
## a file (such as a Module manifest, session configuration file)
function Import-PowerShellDataFile
{
[CmdletBinding(DefaultParameterSetName = "ByPath", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=623621")]
[OutputType("System.Collections.Hashtable")]
param(
[Parameter(ParameterSetName = "ByPath", Position = 0)]
[String[]] $Path,
[Parameter(ParameterSetName = "ByLiteralPath", ValueFromPipelineByPropertyName = $true)]
[Alias("PSPath")]
[String[]] $LiteralPath
)
begin
{
function ThrowInvalidDataFile
{
param($resolvedPath, $extraError)
$errorId = "CouldNotParseAsPowerShellDataFile$extraError"
$errorCategory = [System.Management.Automation.ErrorCategory]::InvalidData
$errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::CouldNotParseAsPowerShellDataFile -f $resolvedPath
$exception = [System.InvalidOperationException]::New($errorMessage)
$errorRecord = [System.Management.Automation.ErrorRecord]::New($exception, $errorId, $errorCategory, $null)
$PSCmdlet.WriteError($errorRecord)
}
}
process
{
foreach($resolvedPath in (Resolve-Path @PSBoundParameters))
{
$parseErrors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile(($resolvedPath.ProviderPath), [ref] $null, [ref] $parseErrors)
if ($parseErrors.Length -gt 0)
{
ThrowInvalidDataFile $resolvedPath
}
else
{
$data = $ast.Find( { $args[0] -is [System.Management.Automation.Language.HashtableAst] }, $false )
if($data)
{
$data.SafeGetValue()
}
else
{
ThrowInvalidDataFile $resolvedPath "NoHashtableRoot"
}
}
}
}
}
## Converts a SDDL string into an object-based representation of a security
## descriptor
function ConvertFrom-SddlString
{
[CmdletBinding(HelpUri = "http://go.microsoft.com/fwlink/?LinkId=623636")]
param(
## The string representing the security descriptor in SDDL syntax
[Parameter(Mandatory, Position = 0)]
[String] $Sddl,
## The type of rights that this SDDL string represents, if any.
[Parameter()]
[ValidateSet(
"FileSystemRights", "RegistryRights", "ActiveDirectoryRights",
"MutexRights", "SemaphoreRights", "CryptoKeyRights",
"EventWaitHandleRights")]
$Type
)
## Translates a SID into a NT Account
function ConvertTo-NtAccount
{
param($Sid)
if($Sid)
{
$securityIdentifier = [System.Security.Principal.SecurityIdentifier] $Sid
try
{
$ntAccount = $securityIdentifier.Translate([System.Security.Principal.NTAccount]).ToString()
}
catch{}
$ntAccount
}
}
## Gets the access rights that apply to an access mask, preferring right types
## of 'Type' if specified.
function Get-AccessRights
{
param($AccessMask, $Type)
## All the types of access rights understood by .NET
$rightTypes = [Ordered] @{
"FileSystemRights" = [System.Security.AccessControl.FileSystemRights]
"RegistryRights" = [System.Security.AccessControl.RegistryRights]
"ActiveDirectoryRights" = [System.DirectoryServices.ActiveDirectoryRights]
"MutexRights" = [System.Security.AccessControl.MutexRights]
"SemaphoreRights" = [System.Security.AccessControl.SemaphoreRights]
"CryptoKeyRights" = [System.Security.AccessControl.CryptoKeyRights]
"EventWaitHandleRights" = [System.Security.AccessControl.EventWaitHandleRights]
}
$typesToExamine = $rightTypes.Values
## If they know the access mask represents a certain type, prefer its names
## (i.e.: CreateLink for the registry over CreateDirectories for the filesystem)
if($Type)
{
$typesToExamine = @($rightTypes[$Type]) + $typesToExamine
}
## Stores the access types we've found that apply
$foundAccess = @()
## Store the access types we've already seen, so that we don't report access
## flags that are essentially duplicate. Many of the access values in the different
## enumerations have the same value but with different names.
$foundValues = @{}
## Go through the entries in the different right types, and see if they apply to the
## provided access mask. If they do, then add that to the result.
foreach($rightType in $typesToExamine)
{
foreach($accessFlag in [Enum]::GetNames($rightType))
{
$longKeyValue = [long] $rightType::$accessFlag
if(-not $foundValues.ContainsKey($longKeyValue))
{
$foundValues[$longKeyValue] = $true
if(($AccessMask -band $longKeyValue) -eq ($longKeyValue))
{
$foundAccess += $accessFlag
}
}
}
}
$foundAccess | Sort-Object
}
## Converts an ACE into a string representation
function ConvertTo-AceString
{
param(
[Parameter(ValueFromPipeline)]
$Ace,
$Type
)
process
{
foreach($aceEntry in $Ace)
{
$AceString = (ConvertTo-NtAccount $aceEntry.SecurityIdentifier) + ": " + $aceEntry.AceQualifier
if($aceEntry.AceFlags -ne "None")
{
$AceString += " " + $aceEntry.AceFlags
}
if($aceEntry.AccessMask)
{
$foundAccess = Get-AccessRights $aceEntry.AccessMask $Type
if($foundAccess)
{
$AceString += " ({0})" -f ($foundAccess -join ", ")
}
}
$AceString
}
}
}
$rawSecurityDescriptor = [Security.AccessControl.CommonSecurityDescriptor]::new($false,$false,$Sddl)
$owner = ConvertTo-NtAccount $rawSecurityDescriptor.Owner
$group = ConvertTo-NtAccount $rawSecurityDescriptor.Group
$discretionaryAcl = ConvertTo-AceString $rawSecurityDescriptor.DiscretionaryAcl $Type
$systemAcl = ConvertTo-AceString $rawSecurityDescriptor.SystemAcl $Type
[PSCustomObject] @{
Owner = $owner
Group = $group
DiscretionaryAcl = @($discretionaryAcl)
SystemAcl = @($systemAcl)
RawDescriptor = $rawSecurityDescriptor
}
}
@@ -0,0 +1,15 @@
@{
GUID="766204A6-330E-4263-A7AB-46C87AFC366C"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
CLRVersion="4.0"
AliasesToExport = @()
FunctionsToExport = @()
CmdletsToExport="Disable-WSManCredSSP", "Enable-WSManCredSSP", "Get-WSManCredSSP", "Set-WSManQuickConfig", "Test-WSMan", "Invoke-WSManAction", "Connect-WSMan", "Disconnect-WSMan", "Get-WSManInstance", "Set-WSManInstance", "Remove-WSManInstance", "New-WSManInstance", "New-WSManSessionOption"
NestedModules="Microsoft.WSMan.Management.dll"
FormatsToProcess="WSMan.format.ps1xml"
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390788'
}
Binary file not shown.
Binary file not shown.
+202
View File
@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>PSRepositoryItemInfo</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.PSRepositoryItemInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>10</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>35</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>10</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>20</Width>
</TableColumnHeader>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Version</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Type</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Repository</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Description</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>PSRepository</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.PSRepository</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>25</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>25</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>20</Width>
</TableColumnHeader>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>PackageManagementProvider</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>InstallationPolicy</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>SourceLocation</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>PSScriptInfo</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.PSScriptInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>10</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>25</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>20</Width>
</TableColumnHeader>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Version</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Author</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Description</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>PSGetDscResourceInfo</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.PSGetCommandInfo</TypeName>
<TypeName>Microsoft.PowerShell.Commands.PSGetDscResourceInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>35</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>10</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>35</Width>
</TableColumnHeader>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Version</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ModuleName</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Repository</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>PSGetRoleCapabilityInfo</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>35</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>10</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>35</Width>
</TableColumnHeader>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Version</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ModuleName</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Repository</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large. Load diff
File renamed without changes.
@@ -3,8 +3,6 @@
Copyright (c) Microsoft Corporation. All rights reserved. Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/ --********************************************************************/
#if CORECLR
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -1679,5 +1677,3 @@ namespace Microsoft.PowerShell.CoreCLR
} }
#endif #endif
#endif
@@ -12,8 +12,6 @@ using System.Diagnostics.CodeAnalysis;
using Microsoft.Win32; using Microsoft.Win32;
using System.Management.Automation.Remoting; using System.Management.Automation.Remoting;
#if CORECLR
#pragma warning disable 1591, 1572, 1571, 1573, 1587, 1570, 0067 #pragma warning disable 1591, 1572, 1571, 1573, 1587, 1570, 0067
#region CLR_STUBS #region CLR_STUBS
@@ -1874,5 +1872,3 @@ namespace System
#pragma warning restore 1591, 1572, 1571, 1573, 1587, 1570, 0067 #pragma warning restore 1591, 1572, 1571, 1573, 1587, 1570, 0067
#endif #endif
#endif
@@ -999,6 +999,25 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
return ClassCache.Values.ToList(); return ClassCache.Values.ToList();
} }
/// <summary>
/// Find cached cim classes defined under specified module
/// </summary>
/// <param name="module"></param>
/// <returns>List of cached cim classes</returns>
public static List<Microsoft.Management.Infrastructure.CimClass> GetCachedClassesForModule(PSModuleInfo module)
{
List<Microsoft.Management.Infrastructure.CimClass> cachedClasses = new List<Microsoft.Management.Infrastructure.CimClass>();
var moduleQualifiedName = String.Format(CultureInfo.InvariantCulture, "{0}\\{1}", module.Name, module.Version.ToString());
foreach (var pair in ClassCache)
{
if(pair.Key.StartsWith(moduleQualifiedName, StringComparison.OrdinalIgnoreCase))
{
cachedClasses.Add(pair.Value.Item2);
}
}
return cachedClasses;
}
/// <summary> /// <summary>
/// Get the file that defined this class. /// Get the file that defined this class.
/// </summary> /// </summary>
@@ -1189,7 +1208,8 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
if (!CacheResourcesFromMultipleModuleVersions && DynamicKeyword.ContainsKeyword(keyword.Keyword)) if (!CacheResourcesFromMultipleModuleVersions && DynamicKeyword.ContainsKeyword(keyword.Keyword))
{ {
var oldKeyword = DynamicKeyword.GetKeyword(keyword.Keyword); var oldKeyword = DynamicKeyword.GetKeyword(keyword.Keyword);
if (!oldKeyword.ImplementingModule.Equals(moduleName, StringComparison.OrdinalIgnoreCase) || oldKeyword.ImplementingModuleVersion != moduleVersion) if (oldKeyword.ImplementingModule == null ||
!oldKeyword.ImplementingModule.Equals(moduleName, StringComparison.OrdinalIgnoreCase) || oldKeyword.ImplementingModuleVersion != moduleVersion)
{ {
var e = PSTraceSource.NewInvalidOperationException(ParserStrings.DuplicateKeywordDefinition, keyword.Keyword); var e = PSTraceSource.NewInvalidOperationException(ParserStrings.DuplicateKeywordDefinition, keyword.Keyword);
e.SetErrorId("DuplicateKeywordDefinition"); e.SetErrorId("DuplicateKeywordDefinition");
@@ -2258,6 +2278,96 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
sb.Append("};"); sb.Append("};");
} }
/// <summary>
/// Gets the line no for DSC Class Resource Get/Set/Test methods
/// </summary>
/// <param name="typeDefinitionAst"></param>
/// <param name="methodsLinePosition"></param>
private static bool GetResourceMethodsLineNumber(TypeDefinitionAst typeDefinitionAst, out Dictionary<string, int> methodsLinePosition)
{
const string getMethodName = "Get";
const string setMethodName = "Set";
const string testMethodName = "Test";
methodsLinePosition = new Dictionary<string, int>(); ;
foreach (var member in typeDefinitionAst.Members)
{
var functionMemberAst = member as FunctionMemberAst;
if (functionMemberAst != null)
{
if (functionMemberAst.Name.Equals(getMethodName, StringComparison.OrdinalIgnoreCase))
{
methodsLinePosition[getMethodName] = functionMemberAst.NameExtent.StartLineNumber;
}
else if (functionMemberAst.Name.Equals(setMethodName, StringComparison.OrdinalIgnoreCase))
{
methodsLinePosition[setMethodName] = functionMemberAst.NameExtent.StartLineNumber;
}
else if (functionMemberAst.Name.Equals(testMethodName, StringComparison.OrdinalIgnoreCase))
{
methodsLinePosition[testMethodName] = functionMemberAst.NameExtent.StartLineNumber;
}
}
}
// All 3 methods (Get/Set/Test) position should be found.
return (methodsLinePosition.Count == 3);
}
/// <summary>
/// Gets the line no for DSC Class Resource Get/Set/Test methods
/// </summary>
/// <param name="moduleInfo"></param>
/// <param name="resourceName"></param>
/// <param name="resourceMethodsLinePosition"></param>
/// <param name="resourceFilePath"></param>
public static bool GetResourceMethodsLinePosition(PSModuleInfo moduleInfo, string resourceName, out Dictionary<string, int> resourceMethodsLinePosition, out string resourceFilePath)
{
resourceMethodsLinePosition = null;
resourceFilePath = string.Empty;
if (moduleInfo == null || string.IsNullOrEmpty(resourceName))
{
return false;
}
IEnumerable<Ast> resourceDefinitions;
List<string> moduleFiles = new List<string>();
if (moduleInfo.RootModule != null)
{
moduleFiles.Add(moduleInfo.Path);
}
if (moduleInfo.NestedModules != null)
{
foreach (var nestedModule in moduleInfo.NestedModules.Where(m => !string.IsNullOrEmpty(m.Path)))
{
moduleFiles.Add(nestedModule.Path);
}
}
foreach (string moduleFile in moduleFiles)
{
if (GetResourceDefinitionsFromModule(moduleFile, out resourceDefinitions, null, null))
{
foreach (var r in resourceDefinitions)
{
var resourceDefnAst = (TypeDefinitionAst)r;
if (!resourceName.Equals(resourceDefnAst.Name, StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (GetResourceMethodsLineNumber(resourceDefnAst, out resourceMethodsLinePosition))
{
resourceFilePath = moduleFile;
return true;
}
}
}
}
return false;
}
private static void ProcessMembers(StringBuilder sb, List<object> embeddedInstanceTypes, TypeDefinitionAst typeDefinitionAst, string className) private static void ProcessMembers(StringBuilder sb, List<object> embeddedInstanceTypes, TypeDefinitionAst typeDefinitionAst, string className)
{ {
foreach (var member in typeDefinitionAst.Members) foreach (var member in typeDefinitionAst.Members)
@@ -2318,15 +2428,14 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
/// ///
/// </summary> /// </summary>
/// <param name="fileName"></param> /// <param name="fileName"></param>
/// <param name="module"></param> /// <param name="resourceDefinitions"></param>
/// <param name="resourcesToImport"></param>
/// <param name="resourcesFound"></param>
/// <param name="functionsToDefine"></param>
/// <param name="errorList"></param> /// <param name="errorList"></param>
/// <param name="extent"></param> /// <param name="extent"></param>
/// <returns></returns> /// <returns></returns>
static bool ImportKeywordsFromScriptFile(string fileName, PSModuleInfo module, ICollection<string> resourcesToImport, ICollection<string> resourcesFound, Dictionary<string, ScriptBlock> functionsToDefine, List<ParseError> errorList, IScriptExtent extent) private static bool GetResourceDefinitionsFromModule (string fileName, out IEnumerable<Ast> resourceDefinitions, List<ParseError> errorList, IScriptExtent extent)
{ {
resourceDefinitions = null;
if (string.IsNullOrEmpty(fileName)) if (string.IsNullOrEmpty(fileName))
{ {
return false; return false;
@@ -2356,7 +2465,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
if (errorList != null && extent != null) if (errorList != null && extent != null)
{ {
List<String> errorMessages = new List<string>(); List<String> errorMessages = new List<string>();
foreach(var error in errors) foreach (var error in errors)
{ {
errorMessages.Add(error.ToString()); errorMessages.Add(error.ToString());
} }
@@ -2366,7 +2475,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
return false; return false;
} }
var resourceDefinitions = ast.FindAll(n => resourceDefinitions = ast.FindAll(n =>
{ {
var typeAst = n as TypeDefinitionAst; var typeAst = n as TypeDefinitionAst;
if (typeAst != null) if (typeAst != null)
@@ -2380,6 +2489,28 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
return false; return false;
}, false); }, false);
return true;
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <param name="module"></param>
/// <param name="resourcesToImport"></param>
/// <param name="resourcesFound"></param>
/// <param name="functionsToDefine"></param>
/// <param name="errorList"></param>
/// <param name="extent"></param>
/// <returns></returns>
static bool ImportKeywordsFromScriptFile(string fileName, PSModuleInfo module, ICollection<string> resourcesToImport, ICollection<string> resourcesFound, Dictionary<string, ScriptBlock> functionsToDefine, List<ParseError> errorList, IScriptExtent extent)
{
IEnumerable<Ast> resourceDefinitions;
if(!GetResourceDefinitionsFromModule(fileName, out resourceDefinitions, errorList, extent))
{
return false;
}
var result = false; var result = false;
var parser = new CimDSCParser(MyClassCallback); var parser = new CimDSCParser(MyClassCallback);
@@ -586,14 +586,34 @@ namespace System.Management.Automation
internal static void VerifyPSEdition(ExternalScriptInfo scriptInfo) internal static void VerifyPSEdition(ExternalScriptInfo scriptInfo)
{ {
string requiresPSEdition = scriptInfo.RequiresPSEdition; if (scriptInfo.RequiresPSEditions != null)
if ((requiresPSEdition != null) && !Utils.IsPSEditionSupported(requiresPSEdition))
{ {
var message = StringUtil.Format(DiscoveryExceptions.RequiresPSEditionNotCompatible, scriptInfo.Name, requiresPSEdition, PSVersionInfo.PSEdition); var isCurrentEditionListed = false;
var ex = new RuntimeException(message); var isRequiresPSEditionSpecified = false;
ex.SetErrorId("ScriptRequiresUnmatchedPSEdition"); foreach (var edition in scriptInfo.RequiresPSEditions)
ex.SetTargetObject(scriptInfo.Name); {
throw ex; isRequiresPSEditionSpecified = true;
isCurrentEditionListed = Utils.IsPSEditionSupported(edition);
if (isCurrentEditionListed)
{
break;
}
}
// Throw an error if required PowerShell editions are specified and without the current PowerShell Edition.
//
if (isRequiresPSEditionSpecified && !isCurrentEditionListed)
{
var specifiedEditionsString = string.Join(",", scriptInfo.RequiresPSEditions);
var message = StringUtil.Format(DiscoveryExceptions.RequiresPSEditionNotCompatible,
scriptInfo.Name,
specifiedEditionsString,
PSVersionInfo.PSEdition);
var ex = new RuntimeException(message);
ex.SetErrorId("ScriptRequiresUnmatchedPSEdition");
ex.SetTargetObject(scriptInfo.Name);
throw ex;
}
} }
} }
@@ -383,12 +383,12 @@ namespace System.Management.Automation
} }
} }
internal string RequiresPSEdition internal IEnumerable<string> RequiresPSEditions
{ {
get get
{ {
var data = GetRequiresData(); var data = GetRequiresData();
return data == null ? null : data.RequiredPSEdition; return data == null ? null : data.RequiredPSEditions;
} }
} }
@@ -3609,7 +3609,18 @@ namespace System.Management.Automation.Runspaces
} }
pse.Runspace = initializedRunspace; pse.Runspace = initializedRunspace;
pse.Invoke(); // Module import should be run in FullLanguage mode since it is running in
// a trusted context.
var savedLanguageMode = pse.Runspace.ExecutionContext.LanguageMode;
pse.Runspace.ExecutionContext.LanguageMode = PSLanguageMode.FullLanguage;
try
{
pse.Invoke();
}
finally
{
pse.Runspace.ExecutionContext.LanguageMode = savedLanguageMode;
}
// Lock down the command visibility to respect default command visibility // Lock down the command visibility to respect default command visibility
if (this.DefaultCommandVisibility != SessionStateEntryVisibility.Public) if (this.DefaultCommandVisibility != SessionStateEntryVisibility.Public)
@@ -9,9 +9,11 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Management.Automation; using System.Management.Automation;
using System.Management.Automation.Internal; using System.Management.Automation.Internal;
using System.Management.Automation.Language;
using System.Management.Automation.Runspaces; using System.Management.Automation.Runspaces;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using Microsoft.Management.Infrastructure; using Microsoft.Management.Infrastructure;
using Dbg = System.Management.Automation.Diagnostics; using Dbg = System.Management.Automation.Diagnostics;
@@ -80,7 +82,7 @@ namespace Microsoft.PowerShell.Commands
/// </summary> /// </summary>
[Parameter(ParameterSetName = ParameterSet_AvailableLocally)] [Parameter(ParameterSetName = ParameterSet_AvailableLocally)]
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)] [Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)]
[ValidateSet("Desktop", "Core")] [ArgumentCompleter(typeof(PSEditionArgumentCompleter))]
public string PSEdition { get; set; } public string PSEdition { get; set; }
/// <summary> /// <summary>
@@ -491,5 +493,28 @@ namespace Microsoft.PowerShell.Commands
} }
} }
} }
/// <summary>
/// PSEditionArgumentCompleter for PowerShell Edition names.
/// </summary>
public class PSEditionArgumentCompleter : IArgumentCompleter
{
/// <summary>
/// CompleteArgument
/// </summary>
public IEnumerable<CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
{
var wordToCompletePattern = WildcardPattern.Get(string.IsNullOrWhiteSpace(wordToComplete) ? "*" : wordToComplete + "*", WildcardOptions.IgnoreCase);
foreach (var edition in Utils.AllowedEditionValues)
{
if (wordToCompletePattern.IsMatch(edition))
{
yield return new CompletionResult(edition, edition, CompletionResultType.Text, edition);
}
}
}
}
} // Microsoft.PowerShell.Commands } // Microsoft.PowerShell.Commands
@@ -3,6 +3,7 @@ Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/ --********************************************************************/
using System; using System;
using System.Linq;
using System.Text; using System.Text;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@@ -886,6 +887,14 @@ namespace Microsoft.PowerShell.Commands
ValidateUriParamterValue(LicenseUri, "LicenseUri"); ValidateUriParamterValue(LicenseUri, "LicenseUri");
ValidateUriParamterValue(IconUri, "IconUri"); ValidateUriParamterValue(IconUri, "IconUri");
if (CompatiblePSEditions != null && (CompatiblePSEditions.Distinct(StringComparer.OrdinalIgnoreCase).Count() != CompatiblePSEditions.Count()))
{
string message = StringUtil.Format(Modules.DuplicateEntriesInCompatiblePSEditions, String.Join(",", CompatiblePSEditions));
var ioe = new InvalidOperationException(message);
var er = new ErrorRecord(ioe, "Modules_DuplicateEntriesInCompatiblePSEditions", ErrorCategory.InvalidArgument, CompatiblePSEditions);
ThrowTerminatingError(er);
}
string action = StringUtil.Format(Modules.CreatingModuleManifestFile, filePath); string action = StringUtil.Format(Modules.CreatingModuleManifestFile, filePath);
if (ShouldProcess(filePath, action)) if (ShouldProcess(filePath, action))
@@ -207,26 +207,26 @@ namespace Microsoft.PowerShell.Commands
var modules = GetModule(new[] { moduleListModule.Name }, true, true); var modules = GetModule(new[] { moduleListModule.Name }, true, true);
if (modules.Count == 0) if (modules.Count == 0)
{ {
string errorMsg = StringUtil.Format(Modules.InvalidFilePathinModuleManifest, moduleListModule.Name, filePath); string errorMsg = StringUtil.Format(Modules.InvalidModuleListinModuleManifest, moduleListModule.Name, filePath);
var errorRecord = new ErrorRecord(new DirectoryNotFoundException(errorMsg), "Modules_InvalidModuleListinModuleManifest", var errorRecord = new ErrorRecord(new DirectoryNotFoundException(errorMsg), "Modules_InvalidModuleListinModuleManifest",
ErrorCategory.ObjectNotFound, _path); ErrorCategory.ObjectNotFound, _path);
WriteError(errorRecord); WriteError(errorRecord);
} }
} }
} }
}
if (module.CompatiblePSEditions.Any()) if (module.CompatiblePSEditions.Any())
{
// The CompatiblePSEditions module manifest key is supported only on PowerShell version '5.1' or higher.
// Ensure that PowerShellVersion module manifest key value is '5.1' or higher.
//
var minimumRequiredPowerShellVersion = new Version(5,1);
if((module.PowerShellVersion == null) || module.PowerShellVersion < minimumRequiredPowerShellVersion)
{ {
string errorMsg = StringUtil.Format(Modules.InvalidPowerShellVersionInModuleManifest, filePath); // The CompatiblePSEditions module manifest key is supported only on PowerShell version '5.1' or higher.
var errorRecord = new ErrorRecord(new ArgumentException(errorMsg), "Modules_InvalidPowerShellVersionInModuleManifest", ErrorCategory.InvalidArgument, _path); // Ensure that PowerShellVersion module manifest key value is '5.1' or higher.
WriteError(errorRecord); //
var minimumRequiredPowerShellVersion = new Version(5,1);
if((module.PowerShellVersion == null) || module.PowerShellVersion < minimumRequiredPowerShellVersion)
{
string errorMsg = StringUtil.Format(Modules.InvalidPowerShellVersionInModuleManifest, filePath);
var errorRecord = new ErrorRecord(new ArgumentException(errorMsg), "Modules_InvalidPowerShellVersionInModuleManifest", ErrorCategory.InvalidArgument, _path);
WriteError(errorRecord);
}
} }
} }
} }
@@ -231,7 +231,8 @@ namespace System.Management.Automation
foreach (var exportedType in exportedTypes) foreach (var exportedType in exportedTypes)
{ {
if (exportedType.Value != null && if (exportedType.Value != null &&
classNameMatcher.IsMatch(exportedType.Value.Name)) classNameMatcher.IsMatch(exportedType.Value.Name) &&
exportedType.Value.IsClass)
{ {
ast = exportedType.Value.Parent.Parent as ScriptBlockAst; ast = exportedType.Value.Parent.Parent as ScriptBlockAst;
if (ast != null) if (ast != null)
@@ -77,6 +77,11 @@ namespace System.Management.Automation
/// </summary> /// </summary>
internal static string WinPEIdentificationRegKey = @"System\CurrentControlSet\Control\MiniNT"; internal static string WinPEIdentificationRegKey = @"System\CurrentControlSet\Control\MiniNT";
/// <summary>
/// Allowed PowerShell Editions
/// </summary>
internal static string[] AllowedEditionValues = { "Desktop", "Core" };
/// <summary> /// <summary>
/// helper fn to check byte[] arg for null. /// helper fn to check byte[] arg for null.
/// </summary> /// </summary>
@@ -522,6 +527,16 @@ namespace System.Management.Automation
return PSVersionInfo.PSEdition.Equals(checkEdition, StringComparison.OrdinalIgnoreCase); return PSVersionInfo.PSEdition.Equals(checkEdition, StringComparison.OrdinalIgnoreCase);
} }
/// <summary>
/// Checks whether the specified edition values is allowed.
/// </summary>
/// <param name="editionValue">Edition value to check</param>
/// <returns>true if allowed, false otherwise</returns>
internal static bool IsValidPSEditionValue(string editionValue)
{
return AllowedEditionValues.Contains(editionValue, StringComparer.OrdinalIgnoreCase);
}
/// <summary> /// <summary>
/// Checks whether current monad session supports NetFrameworkVersion specified /// Checks whether current monad session supports NetFrameworkVersion specified
/// by checkVersion. The specified version is treated as the the minimum required /// by checkVersion. The specified version is treated as the the minimum required
@@ -2705,7 +2705,7 @@ namespace System.Management.Automation.Language
{ {
simpleConfigurationNameValue = outValue as string; simpleConfigurationNameValue = outValue as string;
if (simpleConfigurationNameValue == null || if (simpleConfigurationNameValue == null ||
!System.Text.RegularExpressions.Regex.IsMatch(simpleConfigurationNameValue, "^[A-Za-z][A-Za-z0-9_]*$")) !System.Text.RegularExpressions.Regex.IsMatch(simpleConfigurationNameValue, "^[A-Za-z][A-Za-z0-9_./-]*$"))
{ {
// This is actually a semantics check, the syntax is fine at this point. // This is actually a semantics check, the syntax is fine at this point.
// Continue parsing to get as much information as possible // Continue parsing to get as much information as possible
@@ -708,6 +708,8 @@ namespace System.Management.Automation.Language
Utils.EmptyReadOnlyCollection<string>(); Utils.EmptyReadOnlyCollection<string>();
internal static readonly ReadOnlyCollection<ModuleSpecification> EmptyModuleCollection = internal static readonly ReadOnlyCollection<ModuleSpecification> EmptyModuleCollection =
Utils.EmptyReadOnlyCollection<ModuleSpecification>(); Utils.EmptyReadOnlyCollection<ModuleSpecification>();
internal static readonly ReadOnlyCollection<string> EmptyEditionCollection =
Utils.EmptyReadOnlyCollection<string>();
/// <summary> /// <summary>
/// The application id this script requires, specified like: /// The application id this script requires, specified like:
@@ -726,9 +728,9 @@ namespace System.Management.Automation.Language
/// <summary> /// <summary>
/// The PowerShell Edition this script requires, specified like: /// The PowerShell Edition this script requires, specified like:
/// <code>#requires -PSEdition Desktop</code> /// <code>#requires -PSEdition Desktop</code>
/// If no PSEdition has been specified, this property is null. /// If no PSEdition has been specified, this property is an empty collection.
/// </summary> /// </summary>
public string RequiredPSEdition { get; internal set; } public ReadOnlyCollection<string> RequiredPSEditions { get; internal set; }
/// <summary> /// <summary>
/// The modules this script requires, specified like: /// The modules this script requires, specified like:
@@ -1516,7 +1516,7 @@ namespace System.Management.Automation.Language
string requiredShellId = null; string requiredShellId = null;
Version requiredVersion = null; Version requiredVersion = null;
string requiredEdition = null; List<string> requiredEditions = null;
List<ModuleSpecification> requiredModules = null; List<ModuleSpecification> requiredModules = null;
List<PSSnapInSpecification> requiredSnapins = null; List<PSSnapInSpecification> requiredSnapins = null;
List<string> requiredAssemblies = null; List<string> requiredAssemblies = null;
@@ -1565,7 +1565,7 @@ namespace System.Management.Automation.Language
{ {
HandleRequiresParameter(parameter, commandAst.CommandElements, snapinSpecified, HandleRequiresParameter(parameter, commandAst.CommandElements, snapinSpecified,
ref i, ref snapinName, ref snapinVersion, ref i, ref snapinName, ref snapinVersion,
ref requiredShellId, ref requiredVersion, ref requiredEdition, ref requiredModules, ref requiredAssemblies, ref requiresElevation); ref requiredShellId, ref requiredVersion, ref requiredEditions, ref requiredModules, ref requiredAssemblies, ref requiresElevation);
} }
else else
{ {
@@ -1584,7 +1584,9 @@ namespace System.Management.Automation.Language
{ {
RequiredApplicationId = requiredShellId, RequiredApplicationId = requiredShellId,
RequiredPSVersion = requiredVersion, RequiredPSVersion = requiredVersion,
RequiredPSEdition = requiredEdition, RequiredPSEditions = requiredEditions != null
? new ReadOnlyCollection<string>(requiredEditions)
: ScriptRequirements.EmptyEditionCollection,
RequiresPSSnapIns = requiredSnapins != null RequiresPSSnapIns = requiredSnapins != null
? new ReadOnlyCollection<PSSnapInSpecification>(requiredSnapins) ? new ReadOnlyCollection<PSSnapInSpecification>(requiredSnapins)
: ScriptRequirements.EmptySnapinCollection, : ScriptRequirements.EmptySnapinCollection,
@@ -1614,7 +1616,7 @@ namespace System.Management.Automation.Language
ref Version snapinVersion, ref Version snapinVersion,
ref string requiredShellId, ref string requiredShellId,
ref Version requiredVersion, ref Version requiredVersion,
ref string requiredEdition, ref List<string> requiredEditions,
ref List<ModuleSpecification> requiredModules, ref List<ModuleSpecification> requiredModules,
ref List<string> requiredAssemblies, ref List<string> requiredAssemblies,
ref bool requiresElevation) ref bool requiresElevation)
@@ -1680,19 +1682,23 @@ namespace System.Management.Automation.Language
} }
else if (editionToken.StartsWith(parameter.ParameterName, StringComparison.OrdinalIgnoreCase)) else if (editionToken.StartsWith(parameter.ParameterName, StringComparison.OrdinalIgnoreCase))
{ {
if (!(argumentValue is string)) if (requiredEditions != null)
{
ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, editionToken);
return;
}
if (requiredEdition != null)
{ {
ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, editionToken); ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, editionToken);
return; return;
} }
requiredEdition = (string)argumentValue; if (argumentValue is string || !(argumentValue is IEnumerable))
{
requiredEditions = HandleRequiresPSEditionArgument(argumentAst, argumentValue, ref requiredEditions);
}
else
{
foreach (var arg in (IEnumerable)argumentValue)
{
requiredEditions = HandleRequiresPSEditionArgument(argumentAst, arg, ref requiredEditions);
}
}
} }
else if (versionToken.StartsWith(parameter.ParameterName, StringComparison.OrdinalIgnoreCase)) else if (versionToken.StartsWith(parameter.ParameterName, StringComparison.OrdinalIgnoreCase))
{ {
@@ -1787,6 +1793,34 @@ namespace System.Management.Automation.Language
return requiredAssemblies; return requiredAssemblies;
} }
private List<string> HandleRequiresPSEditionArgument(Ast argumentAst, object arg, ref List<string> requiredEditions)
{
if (!(arg is string))
{
ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, editionToken);
}
else
{
if (requiredEditions == null)
requiredEditions = new List<string>();
var edition = (string) arg;
if (!Utils.IsValidPSEditionValue(edition))
{
ReportError(argumentAst.Extent, () => ParserStrings.RequiresPSEditionInvalid, editionToken);
}
if (!requiredEditions.Contains(edition, StringComparer.OrdinalIgnoreCase))
{
requiredEditions.Add(edition);
}
else
{
ReportError(argumentAst.Extent, () => ParserStrings.RequiresPSEditionValueIsAlreadySpecified, editionToken);
}
}
return requiredEditions;
}
#endregion Requires #endregion Requires
#endregion Comments #endregion Comments
@@ -323,28 +323,39 @@ namespace System.Management.Automation.Runspaces
remoteRunspace.PSSessionName = name; remoteRunspace.PSSessionName = name;
} }
string fullShellName = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>( // WSMan session
remoteRunspace.ConnectionInfo, if (remoteRunspace.ConnectionInfo is WSManConnectionInfo)
"ShellUri", string.Empty);
shell = GetDisplayShellName(fullShellName);
if (remoteRunspace.ConnectionInfo is VMConnectionInfo)
{
computerType = TargetMachineType.VirtualMachine;
}
else if (remoteRunspace.ConnectionInfo is ContainerConnectionInfo)
{
computerType = TargetMachineType.Container;
}
else if (remoteRunspace.ConnectionInfo is WSManConnectionInfo)
{ {
computerType = TargetMachineType.RemoteMachine; computerType = TargetMachineType.RemoteMachine;
string fullShellName = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(
remoteRunspace.ConnectionInfo,
"ShellUri", string.Empty);
shell = GetDisplayShellName(fullShellName);
return;
} }
else
// VM session
VMConnectionInfo vmConnectionInfo = remoteRunspace.ConnectionInfo as VMConnectionInfo;
if (vmConnectionInfo != null)
{ {
Dbg.Assert(false, "Invalid Runspace"); computerType = TargetMachineType.VirtualMachine;
shell = vmConnectionInfo.ConfigurationName;
return;
} }
// Container session
ContainerConnectionInfo containerConnectionInfo = remoteRunspace.ConnectionInfo as ContainerConnectionInfo;
if (containerConnectionInfo != null)
{
computerType = TargetMachineType.Container;
shell = containerConnectionInfo.ContainerProc.ConfigurationName;
return;
}
// We only support WSMan/VM/Container sessions now.
Dbg.Assert(false, "Invalid Runspace");
} }
#endregion Constructor #endregion Constructor
@@ -204,10 +204,15 @@ namespace Microsoft.PowerShell.Commands
{ {
string msgAppDomainName = (!string.IsNullOrEmpty(appDomainName)) ? appDomainName : NamedPipeUtils.DefaultAppDomainName; string msgAppDomainName = (!string.IsNullOrEmpty(appDomainName)) ? appDomainName : NamedPipeUtils.DefaultAppDomainName;
// Unwrap inner exception for original error message, if any.
string errorMessage = (e.InnerException != null) ? (e.InnerException.Message ?? string.Empty) : string.Empty;
ThrowTerminatingError( ThrowTerminatingError(
new ErrorRecord( new ErrorRecord(
new RuntimeException(StringUtil.Format(RemotingErrorIdStrings.EnterPSHostProcessCannotConnectToProcess, msgAppDomainName, procId), new RuntimeException(
e.InnerException), StringUtil.Format(RemotingErrorIdStrings.EnterPSHostProcessCannotConnectToProcess,
msgAppDomainName, procId, errorMessage),
e.InnerException),
"EnterPSHostProcessCannotConnectToProcess", "EnterPSHostProcessCannotConnectToProcess",
ErrorCategory.OperationTimeout, ErrorCategory.OperationTimeout,
this)); this));
@@ -627,7 +632,18 @@ namespace Microsoft.PowerShell.Commands
private set; private set;
} }
#endregion #if !CORECLR
/// <summary>
/// Main window title of the process
/// </summary>
public string MainWindowTitle
{
get;
private set;
}
#endif
#endregion
#region Constructors #region Constructors
@@ -644,6 +660,17 @@ namespace Microsoft.PowerShell.Commands
if (string.IsNullOrEmpty(processName)) { throw new PSArgumentNullException("processName"); } if (string.IsNullOrEmpty(processName)) { throw new PSArgumentNullException("processName"); }
if (string.IsNullOrEmpty(appDomainName)) { throw new PSArgumentNullException("appDomainName"); } if (string.IsNullOrEmpty(appDomainName)) { throw new PSArgumentNullException("appDomainName"); }
#if !CORECLR
MainWindowTitle = String.Empty;
try
{
var proc = System.Diagnostics.Process.GetProcessById(processId);
MainWindowTitle = proc.MainWindowTitle ?? string.Empty;
}
catch (ArgumentException) { }
catch (InvalidOperationException) { }
#endif
this.ProcessName = processName; this.ProcessName = processName;
this.ProcessId = processId; this.ProcessId = processId;
this.AppDomainName = appDomainName; this.AppDomainName = appDomainName;
@@ -263,18 +263,38 @@ namespace Microsoft.PowerShell.Commands
} }
/// <summary> /// <summary>
/// For WSMan session:
/// If this parameter is not specified then the value specified in /// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If /// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used. /// this is not set as well, then Microsoft.PowerShell is used.
///
/// For VM/Container sessions:
/// If this parameter is not specified then no configuration is used.
/// </summary> /// </summary>
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ComputerNameParameterSet)] ParameterSetName = InvokeCommandCommand.ComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.UriParameterSet)] ParameterSetName = InvokeCommandCommand.UriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathComputerNameParameterSet)] ParameterSetName = InvokeCommandCommand.FilePathComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)] ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.VMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.VMNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathVMNameParameterSet)]
public override String ConfigurationName public override String ConfigurationName
{ {
get get
@@ -774,6 +794,23 @@ namespace Microsoft.PowerShell.Commands
return; return;
} }
if (String.IsNullOrEmpty(ConfigurationName))
{
if ((ParameterSetName == InvokeCommandCommand.ComputerNameParameterSet) ||
(ParameterSetName == InvokeCommandCommand.UriParameterSet) ||
(ParameterSetName == InvokeCommandCommand.FilePathComputerNameParameterSet) ||
(ParameterSetName == InvokeCommandCommand.FilePathUriParameterSet))
{
// set to default value for WSMan session
ConfigurationName = ResolveShell(null);
}
else
{
// convert null to String.Empty for VM/Container session
ConfigurationName = String.Empty;
}
}
base.BeginProcessing(); base.BeginProcessing();
// create collection of input writers here // create collection of input writers here
@@ -1761,14 +1798,14 @@ namespace Microsoft.PowerShell.Commands
ErrorRecord errorRecord = streamObject.Value as ErrorRecord; ErrorRecord errorRecord = streamObject.Value as ErrorRecord;
// //
// In case of PSDirectCredentialException, we should output the precise error message // In case of PSDirectException, we should output the precise error message
// in inner exception instead of the generic one in outer exception. // in inner exception instead of the generic one in outer exception.
// //
if ((errorRecord != null) && if ((errorRecord != null) &&
(errorRecord.Exception != null) && (errorRecord.Exception != null) &&
(errorRecord.Exception.InnerException != null)) (errorRecord.Exception.InnerException != null))
{ {
PSDirectCredentialException ex = errorRecord.Exception.InnerException as PSDirectCredentialException; PSDirectException ex = errorRecord.Exception.InnerException as PSDirectException;
if (ex != null) if (ex != null)
{ {
streamObject.Value = new ErrorRecord(errorRecord.Exception.InnerException, streamObject.Value = new ErrorRecord(errorRecord.Exception.InnerException,
@@ -243,7 +243,6 @@ namespace Microsoft.PowerShell.Commands
} }
return resolvedShell; return resolvedShell;
} }
/// <summary> /// <summary>
@@ -551,29 +550,6 @@ namespace Microsoft.PowerShell.Commands
} }
private SwitchParameter useSSL; private SwitchParameter useSSL;
/// <summary>
/// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = PSRemotingBaseCmdlet.ComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = PSRemotingBaseCmdlet.UriParameterSet)]
public virtual String ConfigurationName
{
get
{
return shell;
}
set
{
shell = ResolveShell(value);
}
}
private String shell;
/// <summary> /// <summary>
/// This parameters specifies the appname which identifies the connection /// This parameters specifies the appname which identifies the connection
/// end point on the remote machine. If this parameter is not specified /// end point on the remote machine. If this parameter is not specified
@@ -879,11 +855,6 @@ namespace Microsoft.PowerShell.Commands
idleTimeout / 1000, BaseTransportManager.MinimumIdleTimeout / 1000)); idleTimeout / 1000, BaseTransportManager.MinimumIdleTimeout / 1000));
} }
if (String.IsNullOrEmpty(shell))
{
shell = ResolveShell(null);
}
if (String.IsNullOrEmpty(appName)) if (String.IsNullOrEmpty(appName))
{ {
appName = ResolveAppName(null); appName = ResolveAppName(null);
@@ -1131,6 +1102,54 @@ namespace Microsoft.PowerShell.Commands
} }
private string[] containerName; private string[] containerName;
/// <summary>
/// For WSMan session:
/// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used.
///
/// For VM/Container sessions:
/// If this parameter is not specified then no configuration is used.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.UriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.VMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.VMNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.FilePathVMNameParameterSet)]
public virtual String ConfigurationName
{
get
{
return shell;
}
set
{
// Only InvokeCommandCommand may enter here,
// which will call ResolveShell() if needed.
shell = value;
}
}
private String shell;
#endregion Parameters #endregion Parameters
#region Private Methods #region Private Methods
@@ -1432,7 +1451,7 @@ namespace Microsoft.PowerShell.Commands
try try
{ {
connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index]); connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index], this.ConfigurationName);
remoteRunspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), remoteRunspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(),
connectionInfo, this.Host, null, null, -1); connectionInfo, this.Host, null, null, -1);
@@ -1509,11 +1528,11 @@ namespace Microsoft.PowerShell.Commands
// //
if (isContainerIdSet) if (isContainerIdSet)
{ {
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
else else
{ {
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
resolvedNameList.Add(connectionInfo.ComputerName); resolvedNameList.Add(connectionInfo.ComputerName);
@@ -2355,6 +2374,21 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
#region Private / Protected Methods #region Private / Protected Methods
/// <summary>
/// Gets the matching runspaces based on the parameterset
/// </summary>
/// <param name="writeErrorOnNoMatch">write an error record when
/// no matches are found</param>
/// <param name="writeobject">if true write the object down
/// the pipeline</param>
/// <returns>list of matching runspaces</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
protected Dictionary<Guid, PSSession> GetMatchingRunspaces(bool writeobject,
bool writeErrorOnNoMatch)
{
return GetMatchingRunspaces(writeobject, writeErrorOnNoMatch, SessionFilterState.All, null);
}
/// <summary> /// <summary>
/// Gets the matching runspaces based on the parameterset /// Gets the matching runspaces based on the parameterset
/// </summary> /// </summary>
@@ -2363,11 +2397,13 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
/// <param name="writeobject">if true write the object down /// <param name="writeobject">if true write the object down
/// the pipeline</param> /// the pipeline</param>
/// <param name="filterState">Runspace state filter value.</param> /// <param name="filterState">Runspace state filter value.</param>
/// <param name="configurationName">Runspace configuration name filter value.</param>
/// <returns>list of matching runspaces</returns> /// <returns>list of matching runspaces</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
protected Dictionary<Guid, PSSession> GetMatchingRunspaces(bool writeobject, protected Dictionary<Guid, PSSession> GetMatchingRunspaces(bool writeobject,
bool writeErrorOnNoMatch, bool writeErrorOnNoMatch,
SessionFilterState filterState = SessionFilterState.All) SessionFilterState filterState,
String configurationName)
{ {
switch (ParameterSetName) switch (ParameterSetName)
{ {
@@ -2399,49 +2435,49 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
// container id + optional session name // container id + optional session name
case PSRunspaceCmdlet.ContainerIdParameterSet: case PSRunspaceCmdlet.ContainerIdParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, true, true); return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, true, true);
} }
// container id + session instanceid // container id + session instanceid
case PSRunspaceCmdlet.ContainerIdInstanceIdParameterSet: case PSRunspaceCmdlet.ContainerIdInstanceIdParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, true, true); return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, configurationName, true, true);
} }
// container name + optional session name // container name + optional session name
case PSRunspaceCmdlet.ContainerNameParameterSet: case PSRunspaceCmdlet.ContainerNameParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, true, false); return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, true, false);
} }
// container name + session instanceid // container name + session instanceid
case PSRunspaceCmdlet.ContainerNameInstanceIdParameterSet: case PSRunspaceCmdlet.ContainerNameInstanceIdParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, true, false); return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, configurationName, true, false);
} }
// vm Guid + optional session name // vm Guid + optional session name
case PSRunspaceCmdlet.VMIdParameterSet: case PSRunspaceCmdlet.VMIdParameterSet:
{ {
return GetMatchingRunspacesByVMId(writeobject, filterState); return GetMatchingRunspacesByVMId(writeobject, filterState, configurationName);
} }
// vm Guid + session instanceid // vm Guid + session instanceid
case PSRunspaceCmdlet.VMIdInstanceIdParameterSet: case PSRunspaceCmdlet.VMIdInstanceIdParameterSet:
{ {
return GetMatchingRunspacesByVMIdSessionInstanceId(writeobject, filterState); return GetMatchingRunspacesByVMIdSessionInstanceId(writeobject, filterState, configurationName);
} }
// vm name + optional session name // vm name + optional session name
case PSRunspaceCmdlet.VMNameParameterSet: case PSRunspaceCmdlet.VMNameParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, false, false); return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, false, false);
} }
// vm name + session instanceid // vm name + session instanceid
case PSRunspaceCmdlet.VMNameInstanceIdParameterSet: case PSRunspaceCmdlet.VMNameInstanceIdParameterSet:
{ {
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, false, false); return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, configurationName, false, false);
} }
} }
@@ -2708,11 +2744,13 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
/// </summary> /// </summary>
/// <param name="writeobject">if true write the object down the pipeline</param> /// <param name="writeobject">if true write the object down the pipeline</param>
/// <param name="filterState">Runspace state filter value.</param> /// <param name="filterState">Runspace state filter value.</param>
/// <param name="configurationName">Runspace configuration name filter value.</param>
/// <param name="isContainer">if true the target is a container instead of virtual machine</param> /// <param name="isContainer">if true the target is a container instead of virtual machine</param>
/// <param name="useContainerId">if true the input is container id</param> /// <param name="useContainerId">if true the input is container id</param>
/// <returns>list of matching runspaces</returns> /// <returns>list of matching runspaces</returns>
private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerId(bool writeobject, private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerId(bool writeobject,
SessionFilterState filterState, SessionFilterState filterState,
String configurationName,
bool isContainer, bool isContainer,
bool useContainerId) bool useContainerId)
{ {
@@ -2720,6 +2758,8 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
TargetMachineType computerType; TargetMachineType computerType;
bool supportWildChar = false; bool supportWildChar = false;
String[] sessionNames = { "*" }; String[] sessionNames = { "*" };
WildcardPattern configurationNamePattern =
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>(); Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces; List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces;
@@ -2758,13 +2798,15 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
foreach (string sessionName in sessionNames) foreach (string sessionName in sessionNames)
{ {
WildcardPattern sessionNamePattern = WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase); WildcardPattern sessionNamePattern =
String.IsNullOrEmpty(sessionName) ? null : WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
var matchingRunspaceInfos = remoteRunspaceInfos var matchingRunspaceInfos = remoteRunspaceInfos
.Where<PSSession>(session => (supportWildChar ? inputNamePattern.IsMatch(isContainer ? session.ContainerName : session.VMName) .Where<PSSession>(session => (supportWildChar ? inputNamePattern.IsMatch(isContainer ? session.ContainerName : session.VMName)
: inputName.Equals(session.ContainerId)) && : inputName.Equals(session.ContainerId)) &&
sessionNamePattern.IsMatch(session.Name) && ((sessionNamePattern == null) ? true : sessionNamePattern.IsMatch(session.Name)) &&
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
(session.ComputerType == computerType)) (session.ComputerType == computerType))
.ToList<PSSession>(); .ToList<PSSession>();
@@ -2780,17 +2822,21 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
/// </summary> /// </summary>
/// <param name="writeobject">if true write the object down the pipeline</param> /// <param name="writeobject">if true write the object down the pipeline</param>
/// <param name="filterState">Runspace state filter value.</param> /// <param name="filterState">Runspace state filter value.</param>
/// <param name="configurationName">Runspace configuration name filter value.</param>
/// <param name="isContainer">if true the target is a container instead of virtual machine</param> /// <param name="isContainer">if true the target is a container instead of virtual machine</param>
/// <param name="useContainerId">if true the input is container id</param> /// <param name="useContainerId">if true the input is container id</param>
/// <returns>list of matching runspaces</returns> /// <returns>list of matching runspaces</returns>
private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(bool writeobject, private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(bool writeobject,
SessionFilterState filterState, SessionFilterState filterState,
String configurationName,
bool isContainer, bool isContainer,
bool useContainerId) bool useContainerId)
{ {
String[] inputNames; String[] inputNames;
TargetMachineType computerType; TargetMachineType computerType;
bool supportWildChar = false; bool supportWildChar = false;
WildcardPattern configurationNamePattern =
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>(); Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces; List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces;
@@ -2828,6 +2874,7 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
: inputName.Equals(session.ContainerId)) && : inputName.Equals(session.ContainerId)) &&
sessionInstanceId.Equals(session.InstanceId) && sessionInstanceId.Equals(session.InstanceId) &&
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
(session.ComputerType == computerType)) (session.ComputerType == computerType))
.ToList<PSSession>(); .ToList<PSSession>();
@@ -2843,11 +2890,15 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
/// </summary> /// </summary>
/// <param name="writeobject">if true write the object down the pipeline</param> /// <param name="writeobject">if true write the object down the pipeline</param>
/// <param name="filterState">Runspace state filter value.</param> /// <param name="filterState">Runspace state filter value.</param>
/// <param name="configurationName">Runspace configuration name filter value.</param>
/// <returns>list of matching runspaces</returns> /// <returns>list of matching runspaces</returns>
private Dictionary<Guid, PSSession> GetMatchingRunspacesByVMId(bool writeobject, private Dictionary<Guid, PSSession> GetMatchingRunspacesByVMId(bool writeobject,
SessionFilterState filterState) SessionFilterState filterState,
String configurationName)
{ {
String[] sessionNames = { "*" }; String[] sessionNames = { "*" };
WildcardPattern configurationNamePattern =
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>(); Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces; List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces;
@@ -2861,12 +2912,14 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
{ {
foreach (string sessionName in sessionNames) foreach (string sessionName in sessionNames)
{ {
WildcardPattern sessionNamePattern = WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase); WildcardPattern sessionNamePattern =
String.IsNullOrEmpty(sessionName) ? null : WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
var matchingRunspaceInfos = remoteRunspaceInfos var matchingRunspaceInfos = remoteRunspaceInfos
.Where<PSSession>(session => vmId.Equals(session.VMId) && .Where<PSSession>(session => vmId.Equals(session.VMId) &&
sessionNamePattern.IsMatch(session.Name) && ((sessionNamePattern == null) ? true : sessionNamePattern.IsMatch(session.Name)) &&
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
(session.ComputerType == TargetMachineType.VirtualMachine)) (session.ComputerType == TargetMachineType.VirtualMachine))
.ToList<PSSession>(); .ToList<PSSession>();
@@ -2882,10 +2935,14 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
/// </summary> /// </summary>
/// <param name="writeobject">if true write the object down the pipeline</param> /// <param name="writeobject">if true write the object down the pipeline</param>
/// <param name="filterState">Runspace state filter value.</param> /// <param name="filterState">Runspace state filter value.</param>
/// <param name="configurationName">Runspace configuration name filter value.</param>
/// <returns>list of matching runspaces</returns> /// <returns>list of matching runspaces</returns>
private Dictionary<Guid, PSSession> GetMatchingRunspacesByVMIdSessionInstanceId(bool writeobject, private Dictionary<Guid, PSSession> GetMatchingRunspacesByVMIdSessionInstanceId(bool writeobject,
SessionFilterState filterState) SessionFilterState filterState,
String configurationName)
{ {
WildcardPattern configurationNamePattern =
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>(); Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces; List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces;
@@ -2897,6 +2954,7 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
.Where<PSSession>(session => vmId.Equals(session.VMId) && .Where<PSSession>(session => vmId.Equals(session.VMId) &&
sessionInstanceId.Equals(session.InstanceId) && sessionInstanceId.Equals(session.InstanceId) &&
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
(session.ComputerType == TargetMachineType.VirtualMachine)) (session.ComputerType == TargetMachineType.VirtualMachine))
.ToList<PSSession>(); .ToList<PSSession>();
@@ -219,10 +219,67 @@ namespace Microsoft.PowerShell.Commands
} }
private string containerName; private string containerName;
/// <summary>
/// For WSMan sessions:
/// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used.
///
/// For VM/Container sessions:
/// If this parameter is not specified then no configuration is used.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.ComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.UriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.ContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.ContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.VMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = EnterPSSessionCommand.VMNameParameterSet)]
public String ConfigurationName
{
get
{
return shell;
}
set
{
shell = value;
}
}
private String shell;
#endregion #endregion
#region Overrides #region Overrides
/// <summary>
/// Resolves shellname and appname
/// </summary>
protected override void BeginProcessing()
{
base.BeginProcessing();
if (String.IsNullOrEmpty(ConfigurationName))
{
if ((ParameterSetName == EnterPSSessionCommand.ComputerNameParameterSet) ||
(ParameterSetName == EnterPSSessionCommand.UriParameterSet))
{
// set to default value for WSMan session
ConfigurationName = ResolveShell(null);
}
else
{
// convert null to String.Empty for VM/Container session
ConfigurationName = String.Empty;
}
}
}
/// <summary> /// <summary>
/// Process record. /// Process record.
/// </summary> /// </summary>
@@ -1013,7 +1070,7 @@ namespace Microsoft.PowerShell.Commands
try try
{ {
VMConnectionInfo connectionInfo; VMConnectionInfo connectionInfo;
connectionInfo = new VMConnectionInfo(this.Credential, this.VMId, this.VMName); connectionInfo = new VMConnectionInfo(this.Credential, this.VMId, this.VMName, this.ConfigurationName);
remoteRunspace = CreateTemporaryRemoteRunspaceForPowerShellDirect(this.Host, connectionInfo); remoteRunspace = CreateTemporaryRemoteRunspaceForPowerShellDirect(this.Host, connectionInfo);
} }
@@ -1036,28 +1093,37 @@ namespace Microsoft.PowerShell.Commands
WriteError(errorRecord); WriteError(errorRecord);
} }
catch (PSRemotingDataStructureException e) catch (PSRemotingDataStructureException e)
{
ErrorRecord errorRecord;
//
// In case of PSDirectException, we should output the precise error message
// in inner exception instead of the generic one in outer exception.
//
if ((e.InnerException != null) && (e.InnerException is PSDirectException))
{
errorRecord = new ErrorRecord(e.InnerException,
"CreateRemoteRunspaceForVMFailed",
ErrorCategory.InvalidArgument,
null);
}
else
{
errorRecord = new ErrorRecord(e,
"CreateRemoteRunspaceForVMFailed",
ErrorCategory.InvalidOperation,
null);
}
WriteError(errorRecord);
}
catch (Exception e)
{ {
ErrorRecord errorRecord = new ErrorRecord(e, ErrorRecord errorRecord = new ErrorRecord(e,
"CreateRemoteRunspaceForVMFailed", "CreateRemoteRunspaceForVMFailed",
ErrorCategory.InvalidOperation, ErrorCategory.InvalidOperation,
null); null);
//
// In case of PSDirectCredentialException, we should output the precise error message
// in inner exception instead of the generic one in outer exception.
//
if (e.InnerException != null)
{
PSDirectCredentialException ex = e.InnerException as PSDirectCredentialException;
if (ex != null)
{
errorRecord = new ErrorRecord(e.InnerException,
"CreateRemoteRunspaceForVMFailed",
ErrorCategory.InvalidArgument,
null);
}
}
WriteError(errorRecord); WriteError(errorRecord);
} }
@@ -1180,13 +1246,13 @@ namespace Microsoft.PowerShell.Commands
// //
if (!String.IsNullOrEmpty(ContainerId)) if (!String.IsNullOrEmpty(ContainerId))
{ {
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(ContainerId, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(ContainerId, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
else else
{ {
Dbg.Assert(!String.IsNullOrEmpty(ContainerName), "Either ContainerId or ContainerName has to be set."); Dbg.Assert(!String.IsNullOrEmpty(ContainerName), "Either ContainerId or ContainerName has to be set.");
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(ContainerName, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(ContainerName, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
this.ContainerName = connectionInfo.ComputerName; this.ContainerName = connectionInfo.ComputerName;
@@ -1211,6 +1277,31 @@ namespace Microsoft.PowerShell.Commands
WriteError(errorRecord); WriteError(errorRecord);
} }
catch (PSRemotingDataStructureException e)
{
ErrorRecord errorRecord;
//
// In case of PSDirectException, we should output the precise error message
// in inner exception instead of the generic one in outer exception.
//
if ((e.InnerException != null) && (e.InnerException is PSDirectException))
{
errorRecord = new ErrorRecord(e.InnerException,
"CreateRemoteRunspaceForContainerFailed",
ErrorCategory.InvalidOperation,
null);
}
else
{
errorRecord = new ErrorRecord(e,
"CreateRemoteRunspaceForContainerFailed",
ErrorCategory.InvalidOperation,
null);
}
WriteError(errorRecord);
}
catch (Exception e) catch (Exception e)
{ {
ErrorRecord errorRecord = new ErrorRecord(e, ErrorRecord errorRecord = new ErrorRecord(e,
@@ -117,9 +117,13 @@ namespace Microsoft.PowerShell.Commands
private Uri[] uris; private Uri[] uris;
/// <summary> /// <summary>
/// For WSMan sessions:
/// If this parameter is not specified then the value specified in /// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If /// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used. /// this is not set as well, then Microsoft.PowerShell is used.
///
/// For VM/Container sessions:
/// If this parameter is not speficied then all sessions that match other filters are returned.
/// </summary> /// </summary>
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ComputerNameParameterSet)] ParameterSetName = GetPSSessionCommand.ComputerNameParameterSet)]
@@ -129,13 +133,26 @@ namespace Microsoft.PowerShell.Commands
ParameterSetName = GetPSSessionCommand.ConnectionUriParameterSet)] ParameterSetName = GetPSSessionCommand.ConnectionUriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true, [Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ConnectionUriInstanceIdParameterSet)] ParameterSetName = GetPSSessionCommand.ConnectionUriInstanceIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ContainerIdInstanceIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.ContainerNameInstanceIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.VMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.VMIdInstanceIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.VMNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = GetPSSessionCommand.VMNameInstanceIdParameterSet)]
public String ConfigurationName public String ConfigurationName
{ {
get { return shell; } get { return shell; }
set set { shell = value; }
{
shell = ResolveShell(value);
}
} }
private String shell; private String shell;
@@ -367,6 +384,19 @@ namespace Microsoft.PowerShell.Commands
#region Overrides #region Overrides
/// <summary>
/// Resolves shellname
/// </summary>
protected override void BeginProcessing()
{
base.BeginProcessing();
if (ConfigurationName == null)
{
ConfigurationName = string.Empty;
}
}
/// <summary> /// <summary>
/// Get the list of runspaces from the global cache and write them /// Get the list of runspaces from the global cache and write them
/// down. If no computername or instance id is specified then /// down. If no computername or instance id is specified then
@@ -389,7 +419,7 @@ namespace Microsoft.PowerShell.Commands
} }
else else
{ {
GetMatchingRunspaces(true, true, this.State); GetMatchingRunspaces(true, true, this.State, this.ConfigurationName);
} }
} // ProcessRecord } // ProcessRecord
@@ -164,6 +164,40 @@ namespace Microsoft.PowerShell.Commands
} }
private SwitchParameter enableNetworkAccess; private SwitchParameter enableNetworkAccess;
/// <summary>
/// For WSMan sessions:
/// If this parameter is not specified then the value specified in
/// the environment variable DEFAULTREMOTESHELLNAME will be used. If
/// this is not set as well, then Microsoft.PowerShell is used.
///
/// For VM/Container sessions:
/// If this parameter is not specified then no configuration is used.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.ComputerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.UriParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.ContainerIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.ContainerNameParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.VMIdParameterSet)]
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = NewPSSessionCommand.VMNameParameterSet)]
public String ConfigurationName
{
get
{
return shell;
}
set
{
shell = value;
}
}
private String shell;
#endregion Parameters #endregion Parameters
#region Cmdlet Overrides #region Cmdlet Overrides
@@ -180,6 +214,20 @@ namespace Microsoft.PowerShell.Commands
throttleManager.ThrottleComplete += throttleManager.ThrottleComplete +=
new EventHandler<EventArgs>(HandleThrottleComplete); new EventHandler<EventArgs>(HandleThrottleComplete);
if (String.IsNullOrEmpty(ConfigurationName))
{
if ((ParameterSetName == NewPSSessionCommand.ComputerNameParameterSet) ||
(ParameterSetName == NewPSSessionCommand.UriParameterSet))
{
// set to default value for WSMan session
ConfigurationName = ResolveShell(null);
}
else
{
// convert null to String.Empty for VM/Container session
ConfigurationName = String.Empty;
}
}
} // BeginProcessing } // BeginProcessing
/// <summary> /// <summary>
@@ -504,13 +552,13 @@ namespace Microsoft.PowerShell.Commands
Action<Cmdlet> errorWriter = delegate(Cmdlet cmdlet) Action<Cmdlet> errorWriter = delegate(Cmdlet cmdlet)
{ {
// //
// In case of PSDirectCredentialException, we should output the precise error message // In case of PSDirectException, we should output the precise error message
// in inner exception instead of the generic one in outer exception. // in inner exception instead of the generic one in outer exception.
// //
if ((errorRecord.Exception != null) && if ((errorRecord.Exception != null) &&
(errorRecord.Exception.InnerException != null)) (errorRecord.Exception.InnerException != null))
{ {
PSDirectCredentialException ex = errorRecord.Exception.InnerException as PSDirectCredentialException; PSDirectException ex = errorRecord.Exception.InnerException as PSDirectException;
if (ex != null) if (ex != null)
{ {
errorRecord = new ErrorRecord(errorRecord.Exception.InnerException, errorRecord = new ErrorRecord(errorRecord.Exception.InnerException,
@@ -916,7 +964,7 @@ namespace Microsoft.PowerShell.Commands
try try
{ {
connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index]); connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index], this.ConfigurationName);
runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(),
connectionInfo, this.Host, null, rsName, rsId); connectionInfo, this.Host, null, rsName, rsId);
@@ -992,11 +1040,11 @@ namespace Microsoft.PowerShell.Commands
// //
if (isContainerIdSet) if (isContainerIdSet)
{ {
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
else else
{ {
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent); connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
} }
resolvedNameList.Add(connectionInfo.ComputerName); resolvedNameList.Add(connectionInfo.ComputerName);
@@ -30,33 +30,21 @@ namespace System.Management.Automation.Remoting
#region Members #region Members
private System.Net.Sockets.AddressFamily m_AddressFamily; private System.Net.Sockets.AddressFamily m_AddressFamily;
private HyperVSocketFlag m_Flag;
private Guid m_VmId; private Guid m_VmId;
private Guid m_ServiceId; private Guid m_ServiceId;
public const System.Net.Sockets.AddressFamily AF_HYPERV = (System.Net.Sockets.AddressFamily)34; public const System.Net.Sockets.AddressFamily AF_HYPERV = (System.Net.Sockets.AddressFamily)34;
public const int HYPERV_SOCK_ADDR_SIZE = 36; public const int HYPERV_SOCK_ADDR_SIZE = 36;
/// <summary>
/// Supported values of m_Flag.
/// </summary>
public enum HyperVSocketFlag
{
VM = 0,
HyperVContainer = 1
}
#endregion #endregion
#region Constructor #region Constructor
public HyperVSocketEndPoint(System.Net.Sockets.AddressFamily AddrFamily, public HyperVSocketEndPoint(System.Net.Sockets.AddressFamily AddrFamily,
HyperVSocketFlag Flag,
Guid VmId, Guid VmId,
Guid ServiceId) Guid ServiceId)
{ {
m_AddressFamily = AddrFamily; m_AddressFamily = AddrFamily;
m_Flag = Flag;
m_VmId = VmId; m_VmId = VmId;
m_ServiceId = ServiceId; m_ServiceId = ServiceId;
} }
@@ -66,16 +54,6 @@ namespace System.Management.Automation.Remoting
get { return m_AddressFamily; } get { return m_AddressFamily; }
} }
/// <summary>
/// If Flag is 0, the socket connection is for VM.
/// If Flag is 1, the socket connection is for Hyper-V container.
/// </summary>
public HyperVSocketFlag Flag
{
get { return m_Flag; }
set { m_Flag = value; }
}
public Guid VmId public Guid VmId
{ {
get { return m_VmId; } get { return m_VmId; }
@@ -101,11 +79,10 @@ namespace System.Management.Automation.Remoting
return null; return null;
} }
HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(SockAddr.Family, 0, Guid.Empty, Guid.Empty); HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(SockAddr.Family, Guid.Empty, Guid.Empty);
string sockAddress = SockAddr.ToString(); string sockAddress = SockAddr.ToString();
endpoint.Flag = (HyperVSocketFlag)short.Parse(sockAddress.Substring(2, 2), CultureInfo.InvariantCulture);
endpoint.VmId = new Guid(sockAddress.Substring(4, 16)); endpoint.VmId = new Guid(sockAddress.Substring(4, 16));
endpoint.ServiceId = new Guid(sockAddress.Substring(20, 16)); endpoint.ServiceId = new Guid(sockAddress.Substring(20, 16));
@@ -122,7 +99,6 @@ namespace System.Management.Automation.Remoting
} }
if ((m_AddressFamily == endpoint.AddressFamily) && if ((m_AddressFamily == endpoint.AddressFamily) &&
(m_Flag == endpoint.Flag) &&
(m_VmId == endpoint.VmId) && (m_VmId == endpoint.VmId) &&
(m_ServiceId == endpoint.ServiceId)) (m_ServiceId == endpoint.ServiceId))
{ {
@@ -144,7 +120,7 @@ namespace System.Management.Automation.Remoting
byte[] vmId = m_VmId.ToByteArray(); byte[] vmId = m_VmId.ToByteArray();
byte[] serviceId = m_ServiceId.ToByteArray(); byte[] serviceId = m_ServiceId.ToByteArray();
sockAddress[2] = (byte)m_Flag; sockAddress[2] = (byte)0;
for (int i = 0; i < vmId.Length; i++) for (int i = 0; i < vmId.Length; i++)
{ {
@@ -161,7 +137,7 @@ namespace System.Management.Automation.Remoting
public override string ToString() public override string ToString()
{ {
return ((ushort)m_Flag).ToString(CultureInfo.InvariantCulture) + m_VmId.ToString() + m_ServiceId.ToString(); return m_VmId.ToString() + m_ServiceId.ToString();
} }
#endregion #endregion
@@ -288,7 +264,7 @@ namespace System.Management.Automation.Remoting
// TODO: remove below 6 lines of code when .NET supports Hyper-V socket duplication // TODO: remove below 6 lines of code when .NET supports Hyper-V socket duplication
Guid serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); // HV_GUID_VM_SESSION_SERVICE_ID_2 Guid serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); // HV_GUID_VM_SESSION_SERVICE_ID_2
HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, 0, Guid.Empty, serviceId); HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, Guid.Empty, serviceId);
Socket listenSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1); Socket listenSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1);
listenSocket.Bind(endpoint); listenSocket.Bind(endpoint);
@@ -390,6 +366,13 @@ namespace System.Management.Automation.Remoting
#endregion #endregion
#region constants in hvsocket.h
public const int HV_PROTOCOL_RAW = 1;
public const int HVSOCKET_CONTAINER_PASSTHRU = 2;
#endregion
#region Properties #region Properties
/// <summary> /// <summary>
@@ -464,11 +447,31 @@ namespace System.Management.Automation.Remoting
serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220");
} }
_endPoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, _endPoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, vmId, serviceId);
isContainer ? HyperVSocketEndPoint.HyperVSocketFlag.HyperVContainer : HyperVSocketEndPoint.HyperVSocketFlag.VM,
vmId, serviceId);
_socket = new Socket(_endPoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1); _socket = new Socket(_endPoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1);
//
// We need to call SetSocketOption() in order to set up Hyper-V socket connection between container host and Hyper-V container.
// Here is the scenario: the Hyper-V container is inside a utility vm, which is inside the container host
//
if (isContainer)
{
var value = new byte[sizeof(uint)];
value[0] = 1;
try
{
_socket.SetSocketOption((System.Net.Sockets.SocketOptionLevel)HV_PROTOCOL_RAW,
(System.Net.Sockets.SocketOptionName)HVSOCKET_CONTAINER_PASSTHRU,
(byte[])value);
}
catch
{
throw new PSDirectException(
PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure));
}
}
} }
#endregion #endregion
@@ -522,9 +525,11 @@ namespace System.Management.Automation.Remoting
/// connection occurs or the timeout time has ellapsed. /// connection occurs or the timeout time has ellapsed.
/// </summary> /// </summary>
/// <param name="networkCredential">The credential used for authentication</param> /// <param name="networkCredential">The credential used for authentication</param>
/// <param name="isFirstConnection">Whether this is the first connection</param> /// <param name="configurationName">The configuration name of the PS session</param>
/// <param name="isFirstConnection">Whether this is the first connection</param>
public bool Connect( public bool Connect(
NetworkCredential networkCredential, NetworkCredential networkCredential,
string configurationName,
bool isFirstConnection) bool isFirstConnection)
{ {
bool result = false; bool result = false;
@@ -555,11 +560,8 @@ namespace System.Management.Automation.Remoting
null); null);
} }
bool emptyPassword = false; bool emptyPassword = String.IsNullOrEmpty(networkCredential.Password);
if (String.IsNullOrEmpty(networkCredential.Password)) bool emptyConfiguration = String.IsNullOrEmpty(configurationName);
{
emptyPassword = true;
}
Byte[] domain = Encoding.Unicode.GetBytes(networkCredential.Domain); Byte[] domain = Encoding.Unicode.GetBytes(networkCredential.Domain);
Byte[] userName = Encoding.Unicode.GetBytes(networkCredential.UserName); Byte[] userName = Encoding.Unicode.GetBytes(networkCredential.UserName);
@@ -585,7 +587,6 @@ namespace System.Management.Automation.Remoting
{ {
_socket.Send(Encoding.ASCII.GetBytes("EMPTYPW")); _socket.Send(Encoding.ASCII.GetBytes("EMPTYPW"));
_socket.Receive(response); _socket.Receive(response);
_socket.Send(response);
responseString = Encoding.ASCII.GetString(response); responseString = Encoding.ASCII.GetString(response);
} }
else else
@@ -595,18 +596,49 @@ namespace System.Management.Automation.Remoting
_socket.Send(password); _socket.Send(password);
_socket.Receive(response); _socket.Receive(response);
_socket.Send(response);
responseString = Encoding.ASCII.GetString(response); responseString = Encoding.ASCII.GetString(response);
} }
//
// There are 3 cases for the responseString received above.
// - "FAIL": credential is invalid
// - "PASS": credentail is valid, but PowerShell Direct in VM does not support configuration (Server 2016 TP4 and before)
// - "CONF": credentail is valid, and PowerShell Direct in VM supports configuration (Server 2016 TP5 and later)
//
// //
// Credential is invalid. // Credential is invalid.
// //
if (String.Compare(responseString, "FAIL", StringComparison.Ordinal) == 0) if (String.Compare(responseString, "FAIL", StringComparison.Ordinal) == 0)
{ {
throw new PSDirectCredentialException( _socket.Send(response);
throw new PSDirectException(
PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential));
} }
//
// If PowerShell Direct in VM supports configuration, send configuration name.
//
if (String.Compare(responseString, "CONF", StringComparison.Ordinal) == 0)
{
if (emptyConfiguration)
{
_socket.Send(Encoding.ASCII.GetBytes("EMPTYCF"));
}
else
{
_socket.Send(Encoding.ASCII.GetBytes("NONEMPTYCF"));
_socket.Receive(response);
Byte[] configName = Encoding.Unicode.GetBytes(configurationName);
_socket.Send(configName);
}
}
else
{
_socket.Send(response);
}
} }
_streamReader = new StreamReader(_networkStream); _streamReader = new StreamReader(_networkStream);
@@ -320,6 +320,7 @@ namespace System.Management.Automation.Remoting
private readonly object _syncObject; private readonly object _syncObject;
private bool _disposed; private bool _disposed;
private bool _listenerRunning; private bool _listenerRunning;
private string _configurationName;
private StreamReader _streamReader; private StreamReader _streamReader;
private StreamWriter _streamWriter; private StreamWriter _streamWriter;
private PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource(); private PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource();
@@ -366,6 +367,15 @@ namespace System.Management.Automation.Remoting
get { return _listenerRunning; } get { return _listenerRunning; }
} }
/// <summary>
/// Name of session configuration.
/// </summary>
public string ConfigurationName
{
get { return _configurationName; }
set { _configurationName = value; }
}
/// <summary> /// <summary>
/// Accessor for the named pipe reader. /// Accessor for the named pipe reader.
/// </summary> /// </summary>
@@ -795,7 +805,8 @@ namespace System.Management.Automation.Remoting
/// This method supports PowerShell running in "NamedPipeServerMode", which is used for /// This method supports PowerShell running in "NamedPipeServerMode", which is used for
/// PowerShell Direct Windows Server Container connection and management. /// PowerShell Direct Windows Server Container connection and management.
/// </summary> /// </summary>
internal static void RunServerMode() /// <param name="configurationName">name of the configuration to use</param>
internal static void RunServerMode(string configurationName)
{ {
IPCNamedPipeServerEnabled = true; IPCNamedPipeServerEnabled = true;
CreateIPCNamedPipeServerSingleton(); CreateIPCNamedPipeServerSingleton();
@@ -805,6 +816,8 @@ namespace System.Management.Automation.Remoting
throw new RuntimeException(RemotingErrorIdStrings.NamedPipeServerCannotStart); throw new RuntimeException(RemotingErrorIdStrings.NamedPipeServerCannotStart);
} }
IPCNamedPipeServer.ConfigurationName = configurationName;
ManualResetEventSlim clientConnectionEnded = new ManualResetEventSlim(false); ManualResetEventSlim clientConnectionEnded = new ManualResetEventSlim(false);
IPCNamedPipeServer.ListenerEnded -= OnIPCNamedPipeServerEnded; IPCNamedPipeServer.ListenerEnded -= OnIPCNamedPipeServerEnded;
IPCNamedPipeServer.ListenerEnded += (sender, e) => IPCNamedPipeServer.ListenerEnded += (sender, e) =>
@@ -1172,8 +1185,7 @@ namespace System.Management.Automation.Remoting
int lastError = Marshal.GetLastWin32Error(); int lastError = Marshal.GetLastWin32Error();
if (pipeHandle.IsInvalid) if (pipeHandle.IsInvalid)
{ {
throw new PSInvalidOperationException( throw new System.ComponentModel.Win32Exception(lastError);
StringUtil.Format(RemotingErrorIdStrings.CannotConnectNamedPipe, lastError));
} }
try try
@@ -1971,6 +1971,7 @@ namespace System.Management.Automation.Runspaces
private const int _defaultOpenTimeout = 20000; /* 20 seconds. */ private const int _defaultOpenTimeout = 20000; /* 20 seconds. */
private Guid _vmGuid; private Guid _vmGuid;
private string _vmName; private string _vmName;
private string _configurationName;
#endregion #endregion
@@ -1985,6 +1986,15 @@ namespace System.Management.Automation.Runspaces
set { _vmGuid = value; } set { _vmGuid = value; }
} }
/// <summary>
/// Configuration name of the VM session.
/// </summary>
public string ConfigurationName
{
get { return _configurationName; }
set { _configurationName = value; }
}
#endregion #endregion
#region Overrides #region Overrides
@@ -2047,7 +2057,7 @@ namespace System.Management.Automation.Runspaces
internal override RunspaceConnectionInfo InternalCopy() internal override RunspaceConnectionInfo InternalCopy()
{ {
VMConnectionInfo result = new VMConnectionInfo(Credential, VMGuid, ComputerName); VMConnectionInfo result = new VMConnectionInfo(Credential, VMGuid, ComputerName, ConfigurationName);
return result; return result;
} }
@@ -2057,7 +2067,8 @@ namespace System.Management.Automation.Runspaces
this, this,
instanceId, instanceId,
cryptoHelper, cryptoHelper,
VMGuid); VMGuid,
ConfigurationName);
} }
#endregion #endregion
@@ -2070,12 +2081,14 @@ namespace System.Management.Automation.Runspaces
internal VMConnectionInfo( internal VMConnectionInfo(
PSCredential credential, PSCredential credential,
Guid vmGuid, Guid vmGuid,
string vmName) string vmName,
string configurationName)
: base() : base()
{ {
Credential = credential; Credential = credential;
VMGuid = vmGuid; VMGuid = vmGuid;
ComputerName = vmName; ComputerName = vmName;
ConfigurationName = configurationName;
AuthenticationMechanism = AuthenticationMechanism.Default; AuthenticationMechanism = AuthenticationMechanism.Default;
OpenTimeout = _defaultOpenTimeout; OpenTimeout = _defaultOpenTimeout;
@@ -2224,9 +2237,10 @@ namespace System.Management.Automation.Runspaces
/// </summary> /// </summary>
public static ContainerConnectionInfo CreateContainerConnectionInfoById( public static ContainerConnectionInfo CreateContainerConnectionInfoById(
string containerId, string containerId,
bool runAsAdmin) bool runAsAdmin,
string configurationName)
{ {
ContainerProcess containerProc = new ContainerProcess(containerId, null, 0, runAsAdmin); ContainerProcess containerProc = new ContainerProcess(containerId, null, 0, runAsAdmin, configurationName);
return new ContainerConnectionInfo(containerProc); return new ContainerConnectionInfo(containerProc);
} }
@@ -2236,9 +2250,10 @@ namespace System.Management.Automation.Runspaces
/// </summary> /// </summary>
public static ContainerConnectionInfo CreateContainerConnectionInfoByName( public static ContainerConnectionInfo CreateContainerConnectionInfoByName(
string containerName, string containerName,
bool runAsAdmin) bool runAsAdmin,
string configurationName)
{ {
ContainerProcess containerProc = new ContainerProcess(null, containerName, 0, runAsAdmin); ContainerProcess containerProc = new ContainerProcess(null, containerName, 0, runAsAdmin, configurationName);
return new ContainerConnectionInfo(containerProc); return new ContainerConnectionInfo(containerProc);
} }
@@ -2277,6 +2292,7 @@ namespace System.Management.Automation.Runspaces
private string containerName; private string containerName;
private int processId; private int processId;
private bool runAsAdmin = false; private bool runAsAdmin = false;
private string configurationName;
private bool processTerminated = false; private bool processTerminated = false;
private uint errorCode = 0; private uint errorCode = 0;
private string errorMessage = string.Empty; private string errorMessage = string.Empty;
@@ -2339,6 +2355,15 @@ namespace System.Management.Automation.Runspaces
set { runAsAdmin = value; } set { runAsAdmin = value; }
} }
/// <summary>
/// The configuration name of the container session.
/// </summary>
internal string ConfigurationName
{
get { return configurationName; }
set { configurationName = value; }
}
/// <summary> /// <summary>
/// Whether the process in container has terminated. /// Whether the process in container has terminated.
/// </summary> /// </summary>
@@ -2388,12 +2413,13 @@ namespace System.Management.Automation.Runspaces
/// <summary> /// <summary>
/// Creates an instance used for PowerShell Direct for container. /// Creates an instance used for PowerShell Direct for container.
/// </summary> /// </summary>
public ContainerProcess(string containerId, string containerName, int processId, bool runAsAdmin) public ContainerProcess(string containerId, string containerName, int processId, bool runAsAdmin, string configurationName)
{ {
this.ContainerId = containerId; this.ContainerId = containerId;
this.ContainerName = containerName; this.ContainerName = containerName;
this.ProcessId = processId; this.ProcessId = processId;
this.RunAsAdmin = runAsAdmin; this.RunAsAdmin = runAsAdmin;
this.ConfigurationName = configurationName;
if (!String.IsNullOrEmpty(containerId)) if (!String.IsNullOrEmpty(containerId))
{ {
@@ -2565,8 +2591,9 @@ namespace System.Management.Automation.Runspaces
// Windows Server container (i.e., RuntimeId is empty) uses named pipe transport for now. // Windows Server container (i.e., RuntimeId is empty) uses named pipe transport for now.
// //
cmd = string.Format(System.Globalization.CultureInfo.InvariantCulture, cmd = string.Format(System.Globalization.CultureInfo.InvariantCulture,
@"{{""CommandLine"": ""powershell.exe {0} -NoLogo"",""RestrictedToken"": {1}}}", @"{{""CommandLine"": ""powershell.exe {0} -NoLogo {1}"",""RestrictedToken"": {2}}}",
(RuntimeId != Guid.Empty) ? "-so -NoProfile" : "-NamedPipeServerMode", (RuntimeId != Guid.Empty) ? "-so -NoProfile" : "-NamedPipeServerMode",
String.IsNullOrEmpty(ConfigurationName) ? String.Empty : String.Concat("-Config ", ConfigurationName),
(RunAsAdmin) ? "false" : "true"); (RunAsAdmin) ? "false" : "true");
// //
@@ -231,6 +231,7 @@ namespace System.Management.Automation.Remoting
InvalidContainerNameMultiple = 971, InvalidContainerNameMultiple = 971,
InvalidContainerNameNotExist = 972, InvalidContainerNameNotExist = 972,
ContainerSessionConnectFailed = 973, ContainerSessionConnectFailed = 973,
RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure = 974,
// Invoke-Command related error codes. // Invoke-Command related error codes.
InvalidVMIdNotSingle = 981, InvalidVMIdNotSingle = 981,
@@ -698,10 +699,10 @@ namespace System.Management.Automation.Remoting
} }
/// <summary> /// <summary>
/// This exception is used by PowerShell Direct for credential related error. /// This exception is used by PowerShell Direct errors.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class PSDirectCredentialException : RuntimeException public class PSDirectException : RuntimeException
{ {
#region Constructor #region Constructor
@@ -711,7 +712,7 @@ namespace System.Management.Automation.Remoting
/// <param name="message"> /// <param name="message">
/// A localized string as an error message. /// A localized string as an error message.
/// </param> /// </param>
public PSDirectCredentialException(string message) public PSDirectException(string message)
: base(message) : base(message)
{ {
} }
@@ -1264,6 +1264,7 @@ namespace System.Management.Automation.Remoting.Client
#region Private Data #region Private Data
private Guid _vmGuid; private Guid _vmGuid;
private string _configurationName;
private VMConnectionInfo _connectionInfo; private VMConnectionInfo _connectionInfo;
private NetworkCredential _networkCredential; private NetworkCredential _networkCredential;
@@ -1275,7 +1276,8 @@ namespace System.Management.Automation.Remoting.Client
VMConnectionInfo connectionInfo, VMConnectionInfo connectionInfo,
Guid runspaceId, Guid runspaceId,
PSRemotingCryptoHelper cryptoHelper, PSRemotingCryptoHelper cryptoHelper,
Guid vmGuid) Guid vmGuid,
string configurationName)
: base(runspaceId, cryptoHelper) : base(runspaceId, cryptoHelper)
{ {
if (connectionInfo == null) if (connectionInfo == null)
@@ -1285,6 +1287,7 @@ namespace System.Management.Automation.Remoting.Client
_connectionInfo = connectionInfo; _connectionInfo = connectionInfo;
_vmGuid = vmGuid; _vmGuid = vmGuid;
_configurationName = configurationName;
if (connectionInfo.Credential == null) if (connectionInfo.Credential == null)
{ {
@@ -1307,7 +1310,7 @@ namespace System.Management.Automation.Remoting.Client
internal override void CreateAsync() internal override void CreateAsync()
{ {
_client = new RemoteSessionHyperVSocketClient(_vmGuid, true); _client = new RemoteSessionHyperVSocketClient(_vmGuid, true);
if (!_client.Connect(_networkCredential, true)) if (!_client.Connect(_networkCredential, _configurationName, true))
{ {
_client.Dispose(); _client.Dispose();
throw new PSInvalidOperationException( throw new PSInvalidOperationException(
@@ -1321,7 +1324,7 @@ namespace System.Management.Automation.Remoting.Client
// TODO: remove below 3 lines when Hyper-V socket duplication is supported in .NET framework. // TODO: remove below 3 lines when Hyper-V socket duplication is supported in .NET framework.
_client.Dispose(); _client.Dispose();
_client = new RemoteSessionHyperVSocketClient(_vmGuid, false); _client = new RemoteSessionHyperVSocketClient(_vmGuid, false);
if (!_client.Connect(_networkCredential, false)) if (!_client.Connect(_networkCredential, _configurationName, false))
{ {
_client.Dispose(); _client.Dispose();
throw new PSInvalidOperationException( throw new PSInvalidOperationException(
@@ -1380,7 +1383,7 @@ namespace System.Management.Automation.Remoting.Client
internal override void CreateAsync() internal override void CreateAsync()
{ {
_client = new RemoteSessionHyperVSocketClient(_targetGuid, false, true); _client = new RemoteSessionHyperVSocketClient(_targetGuid, false, true);
if (!_client.Connect(null, false)) if (!_client.Connect(null, String.Empty, false))
{ {
_client.Dispose(); _client.Dispose();
throw new PSInvalidOperationException( throw new PSInvalidOperationException(
@@ -1426,9 +1429,7 @@ namespace System.Management.Automation.Remoting.Client
} }
_connectionInfo = connectionInfo; _connectionInfo = connectionInfo;
_threadName = threadName; _threadName = threadName;
Fragmentor.FragmentSize = RemoteSessionNamedPipeServer.NamedPipeBufferSizeForRemoting; Fragmentor.FragmentSize = RemoteSessionNamedPipeServer.NamedPipeBufferSizeForRemoting;
} }
@@ -552,7 +552,7 @@ namespace System.Management.Automation.Remoting.Server
// AppDomain is not available in CoreCLR // AppDomain is not available in CoreCLR
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomainUnhandledException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomainUnhandledException);
#endif #endif
SingletonInstance.Start(initialCommand); SingletonInstance.Start(initialCommand, namedPipeServer.ConfigurationName);
} }
#endregion #endregion
@@ -480,33 +480,8 @@ namespace System.Management.Automation
/// </summary> /// </summary>
private readonly Hashtable _helpFiles = new Hashtable(); private readonly Hashtable _helpFiles = new Hashtable();
/// <summary> private string GetHelpFile(string helpFile, CmdletInfo cmdletInfo)
/// Finds a help file associated with the given cmdlet
/// </summary>
/// <param name="cmdletInfo"></param>
/// <returns></returns>
private string FindHelpFile(CmdletInfo cmdletInfo)
{ {
if (cmdletInfo == null)
{
throw PSTraceSource.NewArgumentNullException("cmdletInfo");
}
string helpFile = cmdletInfo.HelpFile;
if (String.IsNullOrEmpty(helpFile))
{
if (cmdletInfo.Module != null)
{
if (InitialSessionState.IsEngineModule(cmdletInfo.Module.Name))
{
return System.IO.Path.Combine(cmdletInfo.Module.ModuleBase, CultureInfo.CurrentCulture.Name, engineModuleHelpFileCache[cmdletInfo.Module.Name]);
}
}
return helpFile;
}
string helpFileToLoad = helpFile; string helpFileToLoad = helpFile;
// Get the mshsnapinfo object for this cmdlet. // Get the mshsnapinfo object for this cmdlet.
@@ -560,6 +535,80 @@ namespace System.Management.Automation
return location; return location;
} }
/// <summary>
/// Finds a help file associated with the given cmdlet
/// </summary>
/// <param name="cmdletInfo"></param>
/// <returns></returns>
private string FindHelpFile(CmdletInfo cmdletInfo)
{
if (cmdletInfo == null)
{
throw PSTraceSource.NewArgumentNullException("cmdletInfo");
}
// Get the help file name from the cmdlet metadata
string helpFile = cmdletInfo.HelpFile;
if (String.IsNullOrEmpty(helpFile))
{
if (cmdletInfo.Module != null)
{
if (InitialSessionState.IsEngineModule(cmdletInfo.Module.Name))
{
return System.IO.Path.Combine(cmdletInfo.Module.ModuleBase, CultureInfo.CurrentCulture.Name, engineModuleHelpFileCache[cmdletInfo.Module.Name]);
}
}
return helpFile;
}
// This is the path to the help file.
string location = null;
if (helpFile.EndsWith(".ni.dll-Help.xml"))
{
// For PowerShell on OneCore, we ship Ngen binaries. As a result, the name of the assembly now contains '.ni' on it,
// e.g., <AssemblyName>.ni.dll as supposed to <AssemblyName>.dll.
// When cmdlet metadata is generated for the 'HelpFile' field, we use the name assembly and we append '-Help.xml' to it.
// Because of this, if the cmdlet is part of an N’gen assembly, then 'HelpFile' field will be pointing to a help file which does not exist.
// If this is the case, we remove '.ni' from the help file name and try again.
// For example:
// Ngen assembly name: Microsoft.PowerShell.Commands.Management.ni.dll
// Cmdlet metadata 'HelpFile': Microsoft.PowerShell.Commands.Management.ni.dll-Help.xml
// Actual help file name: Microsoft.PowerShell.Commands.Management.dll-Help.xml
// Make sure that the assembly name contains more than '.ni.dll'
string assemblyName = helpFile.Replace(".ni.dll-Help.xml", "");
if (!String.IsNullOrEmpty(assemblyName))
{
// In the first try, we remove '.ni' from the assembly name and we attempt to find the corresponding help file.
string helpFileName = cmdletInfo.HelpFile.Replace(".ni.dll-Help.xml", ".dll-Help.xml");
location = GetHelpFile(helpFileName, cmdletInfo);
if (String.IsNullOrEmpty(location))
{
// If the help file could not be found, then it is possible that the actual assembly name is something like
// <Name>.ni.dll, e.g., MyAsembly.ni.dll, so let’s try to find the original help file in the cmdlet metadata.
location = GetHelpFile(helpFile, cmdletInfo);
}
}
else
{
// the assembly name is actually '.ni.dll'.
location = GetHelpFile(helpFile, cmdletInfo);
}
}
else
{
location = GetHelpFile(helpFile, cmdletInfo);
}
return location;
}
private void LoadHelpFile(string helpFile, string helpFileIdentifier, string commandName, bool reportErrors) private void LoadHelpFile(string helpFile, string helpFileIdentifier, string commandName, bool reportErrors)
{ {
Exception e = null; Exception e = null;
@@ -81,6 +81,6 @@
}, },
"compile": [ "compile": [
"../windows-build/gen/SYS_AUTO/*.cs" "../windows-build/gen/System.Management.Automation/*.cs"
] ]
} }
@@ -185,7 +185,7 @@ The #requires statement must be in one of the following formats:
<value>The script '{0}' cannot be run because it contained a "#requires" statement for Windows PowerShell {1}. The version of Windows PowerShell that is required by the script does not match the currently running version of Windows PowerShell {2}.</value> <value>The script '{0}' cannot be run because it contained a "#requires" statement for Windows PowerShell {1}. The version of Windows PowerShell that is required by the script does not match the currently running version of Windows PowerShell {2}.</value>
</data> </data>
<data name="RequiresPSEditionNotCompatible" xml:space="preserve"> <data name="RequiresPSEditionNotCompatible" xml:space="preserve">
<value>The script '{0}' cannot be run because it contained a "#requires" statement for PowerShell {1} edition. The edition of PowerShell that is required by the script does not match the currently running PowerShell {2} edition.</value> <value>The script '{0}' cannot be run because it contained a "#requires" statement for PowerShell editions '{1}'. The edition of PowerShell that is required by the script does not match the currently running PowerShell {2} edition.</value>
</data> </data>
<data name="RequiresMissingPSSnapIns" xml:space="preserve"> <data name="RequiresMissingPSSnapIns" xml:space="preserve">
<value>The script '{0}' cannot be run because the following snap-ins that are specified by the "#requires" statements of the script are missing: {1}.</value> <value>The script '{0}' cannot be run because the following snap-ins that are specified by the "#requires" statements of the script are missing: {1}.</value>
@@ -214,6 +214,9 @@
<data name="InvalidPowerShellVersionInModuleManifest" xml:space="preserve"> <data name="InvalidPowerShellVersionInModuleManifest" xml:space="preserve">
<value>The module manifest '{0}' is specified with the CompatiblePSEditions key which is supported only on PowerShell version '5.1' or higher. Update the value of the PowerShellVersion key to '5.1' or higher, and try again.</value> <value>The module manifest '{0}' is specified with the CompatiblePSEditions key which is supported only on PowerShell version '5.1' or higher. Update the value of the PowerShellVersion key to '5.1' or higher, and try again.</value>
</data> </data>
<data name="DuplicateEntriesInCompatiblePSEditions" xml:space="preserve">
<value>The specified value '{0}' for CompatiblePSEditions contains duplicate PowerShell Edition names. Try again after removing the duplicate PowerShell Edition names.</value>
</data>
<data name="ModuleVersionEqualsToVersionFolder" xml:space="preserve"> <data name="ModuleVersionEqualsToVersionFolder" xml:space="preserve">
<value>Version specified in ModuleVersion key is equal to version folder name.</value> <value>Version specified in ModuleVersion key is equal to version folder name.</value>
</data> </data>
@@ -921,6 +921,12 @@ Possible matches are</value>
<data name="RequiresVersionInvalid" xml:space="preserve"> <data name="RequiresVersionInvalid" xml:space="preserve">
<value>The argument for the Version parameter is not valid. Specify a valid Windows PowerShell version, in the format major.minor version.</value> <value>The argument for the Version parameter is not valid. Specify a valid Windows PowerShell version, in the format major.minor version.</value>
</data> </data>
<data name="RequiresPSEditionInvalid" xml:space="preserve">
<value>The argument for the {0} parameter is not valid. Specify a valid PowerShell edition.</value>
</data>
<data name="RequiresPSEditionValueIsAlreadySpecified" xml:space="preserve">
<value>The argument for the {0} parameter contains duplicate values. Do not specify duplicate PowerShell edition values.</value>
</data>
<data name="WildCardModuleNameError" xml:space="preserve"> <data name="WildCardModuleNameError" xml:space="preserve">
<value>Wildcard characters are not supported for module names.</value> <value>Wildcard characters are not supported for module names.</value>
</data> </data>
@@ -1008,7 +1014,7 @@ Possible matches are</value>
<value>A second CIM class definition for '{0}' was found while processing the schema file '{1}'. This class was already defined in the file(s) '{2}'. Remove the redundant definition, and then try again.</value> <value>A second CIM class definition for '{0}' was found while processing the schema file '{1}'. This class was already defined in the file(s) '{2}'. Remove the redundant definition, and then try again.</value>
</data> </data>
<data name="DuplicateKeywordDefinition" xml:space="preserve"> <data name="DuplicateKeywordDefinition" xml:space="preserve">
<value>Keyword '{0}' already defined in the configuration.</value> <value>Resource name '{0}' is already being used by another Resource or Configuration.</value>
</data> </data>
<data name="ClassNameNotSameAsDefiningFile" xml:space="preserve"> <data name="ClassNameNotSameAsDefiningFile" xml:space="preserve">
<value>The class name '{0}' does not match '{1}', the name of the file in which it is defined. Rename either the file name to match the class name or vice versa</value> <value>The class name '{0}' does not match '{1}', the name of the file in which it is defined. Rename either the file name to match the class name or vice versa</value>
@@ -1060,7 +1066,7 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent
<value>Configuration keyword is not allowed in constrainedLanguage mode.</value> <value>Configuration keyword is not allowed in constrainedLanguage mode.</value>
</data> </data>
<data name="InvalidConfigurationName" xml:space="preserve"> <data name="InvalidConfigurationName" xml:space="preserve">
<value>The configuration name '{0}' is not valid. Standard names may only contain letters (a-z, A-Z), numbers (0-9), and underscore (_). The name may not be null or empty, and should start with a letter.</value> <value>The configuration name '{0}' is not valid. Standard names may only contain letters (a-z, A-Z), numbers (0-9), period (.), hyphen (-) and underscore (_). The name may not be null or empty, and should start with a letter.</value>
</data> </data>
<data name="UnsupportedNamedBlockInConfiguration" xml:space="preserve"> <data name="UnsupportedNamedBlockInConfiguration" xml:space="preserve">
<value>Configuration only supports the End block in its body. Begin, Process and DynamicParam blocks are not allowed in a configuration.</value> <value>Configuration only supports the End block in its body. Begin, Process and DynamicParam blocks are not allowed in a configuration.</value>
@@ -1240,6 +1240,9 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<data name="RCAutoDisconnectingError" xml:space="preserve"> <data name="RCAutoDisconnectingError" xml:space="preserve">
<value>Network connectivity to {0} has been lost and the reconnection attempt failed. Please repair the network connection and reconnect using Connect-PSSession or Receive-PSSession.</value> <value>Network connectivity to {0} has been lost and the reconnection attempt failed. Please repair the network connection and reconnect using Connect-PSSession or Receive-PSSession.</value>
</data> </data>
<data name="RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure" xml:space="preserve">
<value>Failed to create an instance of RemoteSessionHyperVSocketClient due to SetSocketOption failure.</value>
</data>
<data name="RemoteSessionHyperVSocketServerConstructorFailure" xml:space="preserve"> <data name="RemoteSessionHyperVSocketServerConstructorFailure" xml:space="preserve">
<value>Failed to create an instance of RemoteSessionHyperVSocketServer.</value> <value>Failed to create an instance of RemoteSessionHyperVSocketServer.</value>
</data> </data>
@@ -1435,7 +1438,7 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<value>{0}[{1}]: {2}</value> <value>{0}[{1}]: {2}</value>
</data> </data>
<data name="EnterPSHostProcessCannotConnectToProcess" xml:space="preserve"> <data name="EnterPSHostProcessCannotConnectToProcess" xml:space="preserve">
<value>Unable to connect to application domain name {0} of process {1}.</value> <value>Unable to connect to application domain name {0} of process {1}. Error: {2}.</value>
</data> </data>
<data name="WSManPluginConnectNoNegotiationData" xml:space="preserve"> <data name="WSManPluginConnectNoNegotiationData" xml:space="preserve">
<value>PowerShell plugin cannot process the Connect operation as required negotiation information is either missing or not complete.</value> <value>PowerShell plugin cannot process the Connect operation as required negotiation information is either missing or not complete.</value>
@@ -1515,9 +1518,6 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<data name="RemoteTransportError" xml:space="preserve"> <data name="RemoteTransportError" xml:space="preserve">
<value>Remote transport error: {0}</value> <value>Remote transport error: {0}</value>
</data> </data>
<data name="CannotConnectNamedPipe" xml:space="preserve">
<value>Unable to open pipe connection for PowerShell IPC. Error code: {0}.</value>
</data>
<data name="CannotConnectContainerNamedPipe" xml:space="preserve"> <data name="CannotConnectContainerNamedPipe" xml:space="preserve">
<value>Unable to open pipe connection for PowerShell in container. Error code: {0}.</value> <value>Unable to open pipe connection for PowerShell in container. Error code: {0}.</value>
</data> </data>
+1 -1
View File
@@ -17,7 +17,7 @@ namespace ConsoleApplication
var outputPath = "../TypeCatalogGen/powershell.inc"; var outputPath = "../TypeCatalogGen/powershell.inc";
// Get a context for our top level project // Get a context for our top level project
var context = ProjectContext.Create("../Microsoft.PowerShell.Linux.Host", NuGetFramework.Parse("netstandardapp1.5")); var context = ProjectContext.Create("../Microsoft.PowerShell.Host", NuGetFramework.Parse("netstandardapp1.5"));
System.IO.File.WriteAllLines(outputPath, System.IO.File.WriteAllLines(outputPath,
// Get the target for the current runtime // Get the target for the current runtime
+9
View File
@@ -13,5 +13,14 @@
"netstandardapp1.5": { "netstandardapp1.5": {
"imports": [ "dnxcore50", "portable-net45+win8" ] "imports": [ "dnxcore50", "portable-net45+win8" ]
} }
},
"runtimes": {
"ubuntu.14.04-x64": { },
"centos.7.1-x64": { },
"win7-x64": { },
"win10-x64": { },
"osx.10.10-x64": { },
"osx.10.11-x64": { }
} }
} }
Loaded 100 of 157 files, more files were not shown because too many files have changed in this diff. Show more