mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Merge pull request #762 from PowerShell/vors/master
Add changes from source-depot branch and Start-ResGen
This commit is contained in:
@@ -506,6 +506,26 @@ function Send-GitDiffToSd {
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
Set-Content -Encoding Ascii -Path "$PSScriptRoot/src/windows-build/gen/$module/$className.cs" -Value $genSource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function script:log([string]$message) {
|
||||
Write-Host -Foreground Green $message
|
||||
@@ -570,3 +590,91 @@ function script:Convert-PSObjectToHashtable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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/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/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/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/NativeCP.resx": "src/System.Management.Automation/resources/NativeCP.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/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/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/RunspacePoolStrings.resx": "src/System.Management.Automation/resources/RunspacePoolStrings.resx",
|
||||
"src/monad/monad/src/engine/resources/RunspaceStrings.resx": "src/System.Management.Automation/resources/RunspaceStrings.resx",
|
||||
|
||||
@@ -36,5 +36,5 @@
|
||||
}
|
||||
},
|
||||
|
||||
"compile": [ "../windows-build/gen/COMMANDS_MANAGEMENT/*.cs" ]
|
||||
"compile": [ "../windows-build/gen/Microsoft.PowerShell.Commands.Management/*.cs" ]
|
||||
}
|
||||
|
||||
+10
-2
@@ -2507,21 +2507,25 @@ function Get-PSImplicitRemotingSession
|
||||
|
||||
// index 0 - "-VMId <vm id>" (VMId is used instead of VMName due to its uniqueness)
|
||||
// index 1 - VM credential
|
||||
// index 2 - "-ConfigurationName <configuration name>" or empty string
|
||||
private const string NewVMRunspaceTemplate = @"
|
||||
$(
|
||||
& $script:NewPSSession `
|
||||
{0} `
|
||||
{1} `
|
||||
{2} `
|
||||
)
|
||||
";
|
||||
|
||||
// index 0 - "-ContainerId <container id>" (ContainerId is used instead of ContainerName due to its uniqueness)
|
||||
// index 1 - "-RunAsAdministrator" or empty string
|
||||
// index 2 - "-ConfigurationName <configuration name>" or empty string
|
||||
private const string NewContainerRunspaceTemplate = @"
|
||||
$(
|
||||
& $script:NewPSSession `
|
||||
{0} `
|
||||
{1} `
|
||||
{2} `
|
||||
)
|
||||
";
|
||||
|
||||
@@ -2530,22 +2534,26 @@ function Get-PSImplicitRemotingSession
|
||||
VMConnectionInfo vmConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as VMConnectionInfo;
|
||||
if (vmConnectionInfo != null)
|
||||
{
|
||||
string vmConfigurationName = vmConnectionInfo.ConfigurationName;
|
||||
return string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
NewVMRunspaceTemplate,
|
||||
/* 0 */ this.GenerateConnectionStringForNewRunspace(),
|
||||
/* 1 */ this.GenerateCredentialParameter());
|
||||
/* 1 */ this.GenerateCredentialParameter(),
|
||||
/* 2 */ String.IsNullOrEmpty(vmConfigurationName) ? String.Empty : String.Concat("-ConfigurationName ", vmConfigurationName));
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerConnectionInfo containerConnectionInfo = this.remoteRunspaceInfo.Runspace.ConnectionInfo as ContainerConnectionInfo;
|
||||
if (containerConnectionInfo != null)
|
||||
{
|
||||
string containerConfigurationName = containerConnectionInfo.ContainerProc.ConfigurationName;
|
||||
return string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
NewContainerRunspaceTemplate,
|
||||
/* 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
|
||||
{
|
||||
|
||||
@@ -44,5 +44,5 @@
|
||||
}
|
||||
},
|
||||
|
||||
"compile": [ "../windows-build/gen/COMMANDS_UTILITY/*.cs" ]
|
||||
"compile": [ "../windows-build/gen/Microsoft.PowerShell.Commands.Utility/*.cs" ]
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Microsoft.PowerShell
|
||||
else if (cpp.NamedPipeServerMode)
|
||||
{
|
||||
ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode");
|
||||
System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode();
|
||||
System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(cpp.ConfigurationName);
|
||||
exitCode = 0;
|
||||
}
|
||||
else if (cpp.SocketServerMode)
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
},
|
||||
|
||||
"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" ]
|
||||
}
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
}
|
||||
},
|
||||
|
||||
"compile": [ "../windows-build/gen/SECURITY/*.cs" ]
|
||||
"compile": [ "../windows-build/gen/Microsoft.PowerShell.Security/*.cs" ]
|
||||
}
|
||||
|
||||
@@ -999,6 +999,25 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
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>
|
||||
/// Get the file that defined this class.
|
||||
/// </summary>
|
||||
@@ -1189,7 +1208,8 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
if (!CacheResourcesFromMultipleModuleVersions && DynamicKeyword.ContainsKeyword(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);
|
||||
e.SetErrorId("DuplicateKeywordDefinition");
|
||||
@@ -2258,6 +2278,96 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
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)
|
||||
{
|
||||
foreach (var member in typeDefinitionAst.Members)
|
||||
@@ -2318,15 +2428,14 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="module"></param>
|
||||
/// <param name="resourcesToImport"></param>
|
||||
/// <param name="resourcesFound"></param>
|
||||
/// <param name="functionsToDefine"></param>
|
||||
/// <param name="resourceDefinitions"></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)
|
||||
private static bool GetResourceDefinitionsFromModule (string fileName, out IEnumerable<Ast> resourceDefinitions, List<ParseError> errorList, IScriptExtent extent)
|
||||
{
|
||||
resourceDefinitions = null;
|
||||
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return false;
|
||||
@@ -2356,7 +2465,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
if (errorList != null && extent != null)
|
||||
{
|
||||
List<String> errorMessages = new List<string>();
|
||||
foreach(var error in errors)
|
||||
foreach (var error in errors)
|
||||
{
|
||||
errorMessages.Add(error.ToString());
|
||||
}
|
||||
@@ -2366,7 +2475,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
return false;
|
||||
}
|
||||
|
||||
var resourceDefinitions = ast.FindAll(n =>
|
||||
resourceDefinitions = ast.FindAll(n =>
|
||||
{
|
||||
var typeAst = n as TypeDefinitionAst;
|
||||
if (typeAst != null)
|
||||
@@ -2380,6 +2489,28 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal
|
||||
return 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 parser = new CimDSCParser(MyClassCallback);
|
||||
|
||||
|
||||
@@ -586,14 +586,34 @@ namespace System.Management.Automation
|
||||
|
||||
internal static void VerifyPSEdition(ExternalScriptInfo scriptInfo)
|
||||
{
|
||||
string requiresPSEdition = scriptInfo.RequiresPSEdition;
|
||||
if ((requiresPSEdition != null) && !Utils.IsPSEditionSupported(requiresPSEdition))
|
||||
if (scriptInfo.RequiresPSEditions != null)
|
||||
{
|
||||
var message = StringUtil.Format(DiscoveryExceptions.RequiresPSEditionNotCompatible, scriptInfo.Name, requiresPSEdition, PSVersionInfo.PSEdition);
|
||||
var ex = new RuntimeException(message);
|
||||
ex.SetErrorId("ScriptRequiresUnmatchedPSEdition");
|
||||
ex.SetTargetObject(scriptInfo.Name);
|
||||
throw ex;
|
||||
var isCurrentEditionListed = false;
|
||||
var isRequiresPSEditionSpecified = false;
|
||||
foreach (var edition in scriptInfo.RequiresPSEditions)
|
||||
{
|
||||
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
|
||||
{
|
||||
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.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
|
||||
if (this.DefaultCommandVisibility != SessionStateEntryVisibility.Public)
|
||||
|
||||
@@ -9,9 +9,11 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Language;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using Microsoft.Management.Infrastructure;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
@@ -80,7 +82,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)]
|
||||
[ValidateSet("Desktop", "Core")]
|
||||
[ArgumentCompleter(typeof(PSEditionArgumentCompleter))]
|
||||
public string PSEdition { get; set; }
|
||||
|
||||
/// <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
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -886,6 +887,14 @@ namespace Microsoft.PowerShell.Commands
|
||||
ValidateUriParamterValue(LicenseUri, "LicenseUri");
|
||||
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);
|
||||
|
||||
if (ShouldProcess(filePath, action))
|
||||
|
||||
@@ -207,26 +207,26 @@ namespace Microsoft.PowerShell.Commands
|
||||
var modules = GetModule(new[] { moduleListModule.Name }, true, true);
|
||||
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",
|
||||
ErrorCategory.ObjectNotFound, _path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
if (module.CompatiblePSEditions.Any())
|
||||
{
|
||||
string errorMsg = StringUtil.Format(Modules.InvalidPowerShellVersionInModuleManifest, filePath);
|
||||
var errorRecord = new ErrorRecord(new ArgumentException(errorMsg), "Modules_InvalidPowerShellVersionInModuleManifest", ErrorCategory.InvalidArgument, _path);
|
||||
WriteError(errorRecord);
|
||||
// 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);
|
||||
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)
|
||||
{
|
||||
if (exportedType.Value != null &&
|
||||
classNameMatcher.IsMatch(exportedType.Value.Name))
|
||||
classNameMatcher.IsMatch(exportedType.Value.Name) &&
|
||||
exportedType.Value.IsClass)
|
||||
{
|
||||
ast = exportedType.Value.Parent.Parent as ScriptBlockAst;
|
||||
if (ast != null)
|
||||
|
||||
@@ -77,6 +77,11 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
internal static string WinPEIdentificationRegKey = @"System\CurrentControlSet\Control\MiniNT";
|
||||
|
||||
/// <summary>
|
||||
/// Allowed PowerShell Editions
|
||||
/// </summary>
|
||||
internal static string[] AllowedEditionValues = { "Desktop", "Core" };
|
||||
|
||||
/// <summary>
|
||||
/// helper fn to check byte[] arg for null.
|
||||
/// </summary>
|
||||
@@ -522,6 +527,16 @@ namespace System.Management.Automation
|
||||
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>
|
||||
/// Checks whether current monad session supports NetFrameworkVersion specified
|
||||
/// 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;
|
||||
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.
|
||||
// Continue parsing to get as much information as possible
|
||||
|
||||
@@ -708,6 +708,8 @@ namespace System.Management.Automation.Language
|
||||
Utils.EmptyReadOnlyCollection<string>();
|
||||
internal static readonly ReadOnlyCollection<ModuleSpecification> EmptyModuleCollection =
|
||||
Utils.EmptyReadOnlyCollection<ModuleSpecification>();
|
||||
internal static readonly ReadOnlyCollection<string> EmptyEditionCollection =
|
||||
Utils.EmptyReadOnlyCollection<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The application id this script requires, specified like:
|
||||
@@ -726,9 +728,9 @@ namespace System.Management.Automation.Language
|
||||
/// <summary>
|
||||
/// The PowerShell Edition this script requires, specified like:
|
||||
/// <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>
|
||||
public string RequiredPSEdition { get; internal set; }
|
||||
public ReadOnlyCollection<string> RequiredPSEditions { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The modules this script requires, specified like:
|
||||
|
||||
@@ -1516,7 +1516,7 @@ namespace System.Management.Automation.Language
|
||||
|
||||
string requiredShellId = null;
|
||||
Version requiredVersion = null;
|
||||
string requiredEdition = null;
|
||||
List<string> requiredEditions = null;
|
||||
List<ModuleSpecification> requiredModules = null;
|
||||
List<PSSnapInSpecification> requiredSnapins = null;
|
||||
List<string> requiredAssemblies = null;
|
||||
@@ -1565,7 +1565,7 @@ namespace System.Management.Automation.Language
|
||||
{
|
||||
HandleRequiresParameter(parameter, commandAst.CommandElements, snapinSpecified,
|
||||
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
|
||||
{
|
||||
@@ -1584,7 +1584,9 @@ namespace System.Management.Automation.Language
|
||||
{
|
||||
RequiredApplicationId = requiredShellId,
|
||||
RequiredPSVersion = requiredVersion,
|
||||
RequiredPSEdition = requiredEdition,
|
||||
RequiredPSEditions = requiredEditions != null
|
||||
? new ReadOnlyCollection<string>(requiredEditions)
|
||||
: ScriptRequirements.EmptyEditionCollection,
|
||||
RequiresPSSnapIns = requiredSnapins != null
|
||||
? new ReadOnlyCollection<PSSnapInSpecification>(requiredSnapins)
|
||||
: ScriptRequirements.EmptySnapinCollection,
|
||||
@@ -1614,7 +1616,7 @@ namespace System.Management.Automation.Language
|
||||
ref Version snapinVersion,
|
||||
ref string requiredShellId,
|
||||
ref Version requiredVersion,
|
||||
ref string requiredEdition,
|
||||
ref List<string> requiredEditions,
|
||||
ref List<ModuleSpecification> requiredModules,
|
||||
ref List<string> requiredAssemblies,
|
||||
ref bool requiresElevation)
|
||||
@@ -1680,19 +1682,23 @@ namespace System.Management.Automation.Language
|
||||
}
|
||||
else if (editionToken.StartsWith(parameter.ParameterName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!(argumentValue is string))
|
||||
{
|
||||
ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, editionToken);
|
||||
return;
|
||||
}
|
||||
|
||||
if (requiredEdition != null)
|
||||
if (requiredEditions != null)
|
||||
{
|
||||
ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, editionToken);
|
||||
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))
|
||||
{
|
||||
@@ -1787,6 +1793,34 @@ namespace System.Management.Automation.Language
|
||||
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 Comments
|
||||
|
||||
@@ -323,28 +323,39 @@ namespace System.Management.Automation.Runspaces
|
||||
remoteRunspace.PSSessionName = name;
|
||||
}
|
||||
|
||||
string fullShellName = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(
|
||||
remoteRunspace.ConnectionInfo,
|
||||
"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)
|
||||
// WSMan session
|
||||
if (remoteRunspace.ConnectionInfo is WSManConnectionInfo)
|
||||
{
|
||||
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
|
||||
|
||||
+30
-3
@@ -204,10 +204,15 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
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(
|
||||
new ErrorRecord(
|
||||
new RuntimeException(StringUtil.Format(RemotingErrorIdStrings.EnterPSHostProcessCannotConnectToProcess, msgAppDomainName, procId),
|
||||
e.InnerException),
|
||||
new RuntimeException(
|
||||
StringUtil.Format(RemotingErrorIdStrings.EnterPSHostProcessCannotConnectToProcess,
|
||||
msgAppDomainName, procId, errorMessage),
|
||||
e.InnerException),
|
||||
"EnterPSHostProcessCannotConnectToProcess",
|
||||
ErrorCategory.OperationTimeout,
|
||||
this));
|
||||
@@ -627,7 +632,18 @@ namespace Microsoft.PowerShell.Commands
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#if !CORECLR
|
||||
/// <summary>
|
||||
/// Main window title of the process
|
||||
/// </summary>
|
||||
public string MainWindowTitle
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
@@ -644,6 +660,17 @@ namespace Microsoft.PowerShell.Commands
|
||||
if (string.IsNullOrEmpty(processName)) { throw new PSArgumentNullException("processName"); }
|
||||
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.ProcessId = processId;
|
||||
this.AppDomainName = appDomainName;
|
||||
|
||||
@@ -263,18 +263,38 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
|
||||
/// <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)]
|
||||
ParameterSetName = InvokeCommandCommand.UriParameterSet)]
|
||||
[Parameter(ValueFromPipelineByPropertyName = true,
|
||||
ParameterSetName = InvokeCommandCommand.FilePathComputerNameParameterSet)]
|
||||
[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
|
||||
{
|
||||
get
|
||||
@@ -774,6 +794,23 @@ namespace Microsoft.PowerShell.Commands
|
||||
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();
|
||||
|
||||
// create collection of input writers here
|
||||
@@ -1761,14 +1798,14 @@ namespace Microsoft.PowerShell.Commands
|
||||
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.
|
||||
//
|
||||
if ((errorRecord != null) &&
|
||||
(errorRecord.Exception != null) &&
|
||||
(errorRecord.Exception.InnerException != null))
|
||||
{
|
||||
PSDirectCredentialException ex = errorRecord.Exception.InnerException as PSDirectCredentialException;
|
||||
PSDirectException ex = errorRecord.Exception.InnerException as PSDirectException;
|
||||
if (ex != null)
|
||||
{
|
||||
streamObject.Value = new ErrorRecord(errorRecord.Exception.InnerException,
|
||||
|
||||
@@ -243,7 +243,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
|
||||
return resolvedShell;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -551,29 +550,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
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>
|
||||
/// This parameters specifies the appname which identifies the connection
|
||||
/// 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));
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(shell))
|
||||
{
|
||||
shell = ResolveShell(null);
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(appName))
|
||||
{
|
||||
appName = ResolveAppName(null);
|
||||
@@ -1131,6 +1102,54 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
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
|
||||
|
||||
#region Private Methods
|
||||
@@ -1432,7 +1451,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
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(),
|
||||
connectionInfo, this.Host, null, null, -1);
|
||||
@@ -1509,11 +1528,11 @@ namespace Microsoft.PowerShell.Commands
|
||||
//
|
||||
if (isContainerIdSet)
|
||||
{
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent);
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent);
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
|
||||
}
|
||||
|
||||
resolvedNameList.Add(connectionInfo.ComputerName);
|
||||
@@ -2355,6 +2374,21 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
|
||||
#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>
|
||||
/// Gets the matching runspaces based on the parameterset
|
||||
/// </summary>
|
||||
@@ -2363,11 +2397,13 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
/// <param name="writeobject">if true write the object down
|
||||
/// the pipeline</param>
|
||||
/// <param name="filterState">Runspace state filter value.</param>
|
||||
/// <param name="configurationName">Runspace configuration name filter value.</param>
|
||||
/// <returns>list of matching runspaces</returns>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
|
||||
protected Dictionary<Guid, PSSession> GetMatchingRunspaces(bool writeobject,
|
||||
bool writeErrorOnNoMatch,
|
||||
SessionFilterState filterState = SessionFilterState.All)
|
||||
SessionFilterState filterState,
|
||||
String configurationName)
|
||||
{
|
||||
switch (ParameterSetName)
|
||||
{
|
||||
@@ -2399,49 +2435,49 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
// container id + optional session name
|
||||
case PSRunspaceCmdlet.ContainerIdParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, true, true);
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, true, true);
|
||||
}
|
||||
|
||||
// container id + session instanceid
|
||||
case PSRunspaceCmdlet.ContainerIdInstanceIdParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, true, true);
|
||||
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, configurationName, true, true);
|
||||
}
|
||||
|
||||
// container name + optional session name
|
||||
case PSRunspaceCmdlet.ContainerNameParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, true, false);
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, true, false);
|
||||
}
|
||||
|
||||
// container name + session instanceid
|
||||
case PSRunspaceCmdlet.ContainerNameInstanceIdParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, true, false);
|
||||
return GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(writeobject, filterState, configurationName, true, false);
|
||||
}
|
||||
|
||||
// vm Guid + optional session name
|
||||
case PSRunspaceCmdlet.VMIdParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByVMId(writeobject, filterState);
|
||||
return GetMatchingRunspacesByVMId(writeobject, filterState, configurationName);
|
||||
}
|
||||
|
||||
// vm Guid + session instanceid
|
||||
case PSRunspaceCmdlet.VMIdInstanceIdParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByVMIdSessionInstanceId(writeobject, filterState);
|
||||
return GetMatchingRunspacesByVMIdSessionInstanceId(writeobject, filterState, configurationName);
|
||||
}
|
||||
|
||||
// vm name + optional session name
|
||||
case PSRunspaceCmdlet.VMNameParameterSet:
|
||||
{
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, false, false);
|
||||
return GetMatchingRunspacesByContainerVMNameContainerId(writeobject, filterState, configurationName, false, false);
|
||||
}
|
||||
|
||||
// vm name + session instanceid
|
||||
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>
|
||||
/// <param name="writeobject">if true write the object down the pipeline</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="useContainerId">if true the input is container id</param>
|
||||
/// <returns>list of matching runspaces</returns>
|
||||
private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerId(bool writeobject,
|
||||
SessionFilterState filterState,
|
||||
String configurationName,
|
||||
bool isContainer,
|
||||
bool useContainerId)
|
||||
{
|
||||
@@ -2720,6 +2758,8 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
TargetMachineType computerType;
|
||||
bool supportWildChar = false;
|
||||
String[] sessionNames = { "*" };
|
||||
WildcardPattern configurationNamePattern =
|
||||
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
|
||||
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
|
||||
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)
|
||||
{
|
||||
WildcardPattern sessionNamePattern = WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
|
||||
WildcardPattern sessionNamePattern =
|
||||
String.IsNullOrEmpty(sessionName) ? null : WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
|
||||
|
||||
var matchingRunspaceInfos = remoteRunspaceInfos
|
||||
.Where<PSSession>(session => (supportWildChar ? inputNamePattern.IsMatch(isContainer ? session.ContainerName : session.VMName)
|
||||
: inputName.Equals(session.ContainerId)) &&
|
||||
sessionNamePattern.IsMatch(session.Name) &&
|
||||
((sessionNamePattern == null) ? true : sessionNamePattern.IsMatch(session.Name)) &&
|
||||
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
|
||||
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
|
||||
(session.ComputerType == computerType))
|
||||
.ToList<PSSession>();
|
||||
|
||||
@@ -2780,17 +2822,21 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
/// </summary>
|
||||
/// <param name="writeobject">if true write the object down the pipeline</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="useContainerId">if true the input is container id</param>
|
||||
/// <returns>list of matching runspaces</returns>
|
||||
private Dictionary<Guid, PSSession> GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(bool writeobject,
|
||||
SessionFilterState filterState,
|
||||
String configurationName,
|
||||
bool isContainer,
|
||||
bool useContainerId)
|
||||
{
|
||||
String[] inputNames;
|
||||
TargetMachineType computerType;
|
||||
bool supportWildChar = false;
|
||||
WildcardPattern configurationNamePattern =
|
||||
String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase);
|
||||
Dictionary<Guid, PSSession> matches = new Dictionary<Guid, PSSession>();
|
||||
List<PSSession> remoteRunspaceInfos = this.RunspaceRepository.Runspaces;
|
||||
|
||||
@@ -2828,6 +2874,7 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
: inputName.Equals(session.ContainerId)) &&
|
||||
sessionInstanceId.Equals(session.InstanceId) &&
|
||||
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
|
||||
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
|
||||
(session.ComputerType == computerType))
|
||||
.ToList<PSSession>();
|
||||
|
||||
@@ -2843,11 +2890,15 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
/// </summary>
|
||||
/// <param name="writeobject">if true write the object down the pipeline</param>
|
||||
/// <param name="filterState">Runspace state filter value.</param>
|
||||
/// <param name="configurationName">Runspace configuration name filter value.</param>
|
||||
/// <returns>list of matching runspaces</returns>
|
||||
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>();
|
||||
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)
|
||||
{
|
||||
WildcardPattern sessionNamePattern = WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
|
||||
WildcardPattern sessionNamePattern =
|
||||
String.IsNullOrEmpty(sessionName) ? null : WildcardPattern.Get(sessionName, WildcardOptions.IgnoreCase);
|
||||
|
||||
var matchingRunspaceInfos = remoteRunspaceInfos
|
||||
.Where<PSSession>(session => vmId.Equals(session.VMId) &&
|
||||
sessionNamePattern.IsMatch(session.Name) &&
|
||||
((sessionNamePattern == null) ? true : sessionNamePattern.IsMatch(session.Name)) &&
|
||||
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
|
||||
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
|
||||
(session.ComputerType == TargetMachineType.VirtualMachine))
|
||||
.ToList<PSSession>();
|
||||
|
||||
@@ -2882,10 +2935,14 @@ private string GetConvertedScript(out List<string> newParameterNames, out List<o
|
||||
/// </summary>
|
||||
/// <param name="writeobject">if true write the object down the pipeline</param>
|
||||
/// <param name="filterState">Runspace state filter value.</param>
|
||||
/// <param name="configurationName">Runspace configuration name filter value.</param>
|
||||
/// <returns>list of matching runspaces</returns>
|
||||
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>();
|
||||
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) &&
|
||||
sessionInstanceId.Equals(session.InstanceId) &&
|
||||
QueryRunspaces.TestRunspaceState(session.Runspace, filterState) &&
|
||||
((configurationNamePattern == null) ? true : configurationNamePattern.IsMatch(session.ConfigurationName)) &&
|
||||
(session.ComputerType == TargetMachineType.VirtualMachine))
|
||||
.ToList<PSSession>();
|
||||
|
||||
|
||||
@@ -219,10 +219,67 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
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
|
||||
|
||||
#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>
|
||||
/// Process record.
|
||||
/// </summary>
|
||||
@@ -1013,7 +1070,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -1036,28 +1093,37 @@ namespace Microsoft.PowerShell.Commands
|
||||
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,
|
||||
"CreateRemoteRunspaceForVMFailed",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorRecord = new ErrorRecord(e,
|
||||
"CreateRemoteRunspaceForVMFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
}
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(e,
|
||||
"CreateRemoteRunspaceForVMFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1180,13 +1246,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
//
|
||||
if (!String.IsNullOrEmpty(ContainerId))
|
||||
{
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(ContainerId, RunAsAdministrator.IsPresent);
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(ContainerId, RunAsAdministrator.IsPresent, this.ConfigurationName);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
@@ -1211,6 +1277,31 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
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)
|
||||
{
|
||||
ErrorRecord errorRecord = new ErrorRecord(e,
|
||||
|
||||
@@ -117,9 +117,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
private Uri[] uris;
|
||||
|
||||
/// <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 speficied then all sessions that match other filters are returned.
|
||||
/// </summary>
|
||||
[Parameter(ValueFromPipelineByPropertyName = true,
|
||||
ParameterSetName = GetPSSessionCommand.ComputerNameParameterSet)]
|
||||
@@ -129,13 +133,26 @@ namespace Microsoft.PowerShell.Commands
|
||||
ParameterSetName = GetPSSessionCommand.ConnectionUriParameterSet)]
|
||||
[Parameter(ValueFromPipelineByPropertyName = true,
|
||||
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
|
||||
{
|
||||
get { return shell; }
|
||||
set
|
||||
{
|
||||
shell = ResolveShell(value);
|
||||
}
|
||||
set { shell = value; }
|
||||
}
|
||||
private String shell;
|
||||
|
||||
@@ -367,6 +384,19 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
#region Overrides
|
||||
|
||||
/// <summary>
|
||||
/// Resolves shellname
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
base.BeginProcessing();
|
||||
|
||||
if (ConfigurationName == null)
|
||||
{
|
||||
ConfigurationName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of runspaces from the global cache and write them
|
||||
/// down. If no computername or instance id is specified then
|
||||
@@ -389,7 +419,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMatchingRunspaces(true, true, this.State);
|
||||
GetMatchingRunspaces(true, true, this.State, this.ConfigurationName);
|
||||
}
|
||||
} // ProcessRecord
|
||||
|
||||
|
||||
@@ -164,6 +164,40 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
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
|
||||
|
||||
#region Cmdlet Overrides
|
||||
@@ -180,6 +214,20 @@ namespace Microsoft.PowerShell.Commands
|
||||
throttleManager.ThrottleComplete +=
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
@@ -504,13 +552,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
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.
|
||||
//
|
||||
if ((errorRecord.Exception != null) &&
|
||||
(errorRecord.Exception.InnerException != null))
|
||||
{
|
||||
PSDirectCredentialException ex = errorRecord.Exception.InnerException as PSDirectCredentialException;
|
||||
PSDirectException ex = errorRecord.Exception.InnerException as PSDirectException;
|
||||
if (ex != null)
|
||||
{
|
||||
errorRecord = new ErrorRecord(errorRecord.Exception.InnerException,
|
||||
@@ -916,7 +964,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
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(),
|
||||
connectionInfo, this.Host, null, rsName, rsId);
|
||||
@@ -992,11 +1040,11 @@ namespace Microsoft.PowerShell.Commands
|
||||
//
|
||||
if (isContainerIdSet)
|
||||
{
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent);
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent);
|
||||
connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName);
|
||||
}
|
||||
|
||||
resolvedNameList.Add(connectionInfo.ComputerName);
|
||||
|
||||
+73
-41
@@ -30,33 +30,21 @@ namespace System.Management.Automation.Remoting
|
||||
#region Members
|
||||
|
||||
private System.Net.Sockets.AddressFamily m_AddressFamily;
|
||||
private HyperVSocketFlag m_Flag;
|
||||
private Guid m_VmId;
|
||||
private Guid m_ServiceId;
|
||||
|
||||
public const System.Net.Sockets.AddressFamily AF_HYPERV = (System.Net.Sockets.AddressFamily)34;
|
||||
public const int HYPERV_SOCK_ADDR_SIZE = 36;
|
||||
|
||||
/// <summary>
|
||||
/// Supported values of m_Flag.
|
||||
/// </summary>
|
||||
public enum HyperVSocketFlag
|
||||
{
|
||||
VM = 0,
|
||||
HyperVContainer = 1
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public HyperVSocketEndPoint(System.Net.Sockets.AddressFamily AddrFamily,
|
||||
HyperVSocketFlag Flag,
|
||||
Guid VmId,
|
||||
Guid ServiceId)
|
||||
{
|
||||
m_AddressFamily = AddrFamily;
|
||||
m_Flag = Flag;
|
||||
m_VmId = VmId;
|
||||
m_ServiceId = ServiceId;
|
||||
}
|
||||
@@ -66,16 +54,6 @@ namespace System.Management.Automation.Remoting
|
||||
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
|
||||
{
|
||||
get { return m_VmId; }
|
||||
@@ -101,11 +79,10 @@ namespace System.Management.Automation.Remoting
|
||||
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();
|
||||
|
||||
endpoint.Flag = (HyperVSocketFlag)short.Parse(sockAddress.Substring(2, 2), CultureInfo.InvariantCulture);
|
||||
endpoint.VmId = new Guid(sockAddress.Substring(4, 16));
|
||||
endpoint.ServiceId = new Guid(sockAddress.Substring(20, 16));
|
||||
|
||||
@@ -122,7 +99,6 @@ namespace System.Management.Automation.Remoting
|
||||
}
|
||||
|
||||
if ((m_AddressFamily == endpoint.AddressFamily) &&
|
||||
(m_Flag == endpoint.Flag) &&
|
||||
(m_VmId == endpoint.VmId) &&
|
||||
(m_ServiceId == endpoint.ServiceId))
|
||||
{
|
||||
@@ -144,7 +120,7 @@ namespace System.Management.Automation.Remoting
|
||||
byte[] vmId = m_VmId.ToByteArray();
|
||||
byte[] serviceId = m_ServiceId.ToByteArray();
|
||||
|
||||
sockAddress[2] = (byte)m_Flag;
|
||||
sockAddress[2] = (byte)0;
|
||||
|
||||
for (int i = 0; i < vmId.Length; i++)
|
||||
{
|
||||
@@ -161,7 +137,7 @@ namespace System.Management.Automation.Remoting
|
||||
|
||||
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
|
||||
@@ -288,7 +264,7 @@ namespace System.Management.Automation.Remoting
|
||||
|
||||
// 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
|
||||
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);
|
||||
listenSocket.Bind(endpoint);
|
||||
@@ -390,6 +366,13 @@ namespace System.Management.Automation.Remoting
|
||||
|
||||
#endregion
|
||||
|
||||
#region constants in hvsocket.h
|
||||
|
||||
public const int HV_PROTOCOL_RAW = 1;
|
||||
public const int HVSOCKET_CONTAINER_PASSTHRU = 2;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
@@ -464,11 +447,31 @@ namespace System.Management.Automation.Remoting
|
||||
serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220");
|
||||
}
|
||||
|
||||
_endPoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV,
|
||||
isContainer ? HyperVSocketEndPoint.HyperVSocketFlag.HyperVContainer : HyperVSocketEndPoint.HyperVSocketFlag.VM,
|
||||
vmId, serviceId);
|
||||
|
||||
_endPoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, vmId, serviceId);
|
||||
|
||||
_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
|
||||
@@ -522,9 +525,11 @@ namespace System.Management.Automation.Remoting
|
||||
/// connection occurs or the timeout time has ellapsed.
|
||||
/// </summary>
|
||||
/// <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(
|
||||
NetworkCredential networkCredential,
|
||||
string configurationName,
|
||||
bool isFirstConnection)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -555,11 +560,8 @@ namespace System.Management.Automation.Remoting
|
||||
null);
|
||||
}
|
||||
|
||||
bool emptyPassword = false;
|
||||
if (String.IsNullOrEmpty(networkCredential.Password))
|
||||
{
|
||||
emptyPassword = true;
|
||||
}
|
||||
bool emptyPassword = String.IsNullOrEmpty(networkCredential.Password);
|
||||
bool emptyConfiguration = String.IsNullOrEmpty(configurationName);
|
||||
|
||||
Byte[] domain = Encoding.Unicode.GetBytes(networkCredential.Domain);
|
||||
Byte[] userName = Encoding.Unicode.GetBytes(networkCredential.UserName);
|
||||
@@ -585,7 +587,6 @@ namespace System.Management.Automation.Remoting
|
||||
{
|
||||
_socket.Send(Encoding.ASCII.GetBytes("EMPTYPW"));
|
||||
_socket.Receive(response);
|
||||
_socket.Send(response);
|
||||
responseString = Encoding.ASCII.GetString(response);
|
||||
}
|
||||
else
|
||||
@@ -595,18 +596,49 @@ namespace System.Management.Automation.Remoting
|
||||
|
||||
_socket.Send(password);
|
||||
_socket.Receive(response);
|
||||
_socket.Send(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.
|
||||
//
|
||||
if (String.Compare(responseString, "FAIL", StringComparison.Ordinal) == 0)
|
||||
{
|
||||
throw new PSDirectCredentialException(
|
||||
_socket.Send(response);
|
||||
|
||||
throw new PSDirectException(
|
||||
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);
|
||||
|
||||
@@ -320,6 +320,7 @@ namespace System.Management.Automation.Remoting
|
||||
private readonly object _syncObject;
|
||||
private bool _disposed;
|
||||
private bool _listenerRunning;
|
||||
private string _configurationName;
|
||||
private StreamReader _streamReader;
|
||||
private StreamWriter _streamWriter;
|
||||
private PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource();
|
||||
@@ -366,6 +367,15 @@ namespace System.Management.Automation.Remoting
|
||||
get { return _listenerRunning; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of session configuration.
|
||||
/// </summary>
|
||||
public string ConfigurationName
|
||||
{
|
||||
get { return _configurationName; }
|
||||
set { _configurationName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accessor for the named pipe reader.
|
||||
/// </summary>
|
||||
@@ -795,7 +805,8 @@ namespace System.Management.Automation.Remoting
|
||||
/// This method supports PowerShell running in "NamedPipeServerMode", which is used for
|
||||
/// PowerShell Direct Windows Server Container connection and management.
|
||||
/// </summary>
|
||||
internal static void RunServerMode()
|
||||
/// <param name="configurationName">name of the configuration to use</param>
|
||||
internal static void RunServerMode(string configurationName)
|
||||
{
|
||||
IPCNamedPipeServerEnabled = true;
|
||||
CreateIPCNamedPipeServerSingleton();
|
||||
@@ -805,6 +816,8 @@ namespace System.Management.Automation.Remoting
|
||||
throw new RuntimeException(RemotingErrorIdStrings.NamedPipeServerCannotStart);
|
||||
}
|
||||
|
||||
IPCNamedPipeServer.ConfigurationName = configurationName;
|
||||
|
||||
ManualResetEventSlim clientConnectionEnded = new ManualResetEventSlim(false);
|
||||
IPCNamedPipeServer.ListenerEnded -= OnIPCNamedPipeServerEnded;
|
||||
IPCNamedPipeServer.ListenerEnded += (sender, e) =>
|
||||
@@ -1172,8 +1185,7 @@ namespace System.Management.Automation.Remoting
|
||||
int lastError = Marshal.GetLastWin32Error();
|
||||
if (pipeHandle.IsInvalid)
|
||||
{
|
||||
throw new PSInvalidOperationException(
|
||||
StringUtil.Format(RemotingErrorIdStrings.CannotConnectNamedPipe, lastError));
|
||||
throw new System.ComponentModel.Win32Exception(lastError);
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -1971,6 +1971,7 @@ namespace System.Management.Automation.Runspaces
|
||||
private const int _defaultOpenTimeout = 20000; /* 20 seconds. */
|
||||
private Guid _vmGuid;
|
||||
private string _vmName;
|
||||
private string _configurationName;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1985,6 +1986,15 @@ namespace System.Management.Automation.Runspaces
|
||||
set { _vmGuid = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration name of the VM session.
|
||||
/// </summary>
|
||||
public string ConfigurationName
|
||||
{
|
||||
get { return _configurationName; }
|
||||
set { _configurationName = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
@@ -2047,7 +2057,7 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
internal override RunspaceConnectionInfo InternalCopy()
|
||||
{
|
||||
VMConnectionInfo result = new VMConnectionInfo(Credential, VMGuid, ComputerName);
|
||||
VMConnectionInfo result = new VMConnectionInfo(Credential, VMGuid, ComputerName, ConfigurationName);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2057,7 +2067,8 @@ namespace System.Management.Automation.Runspaces
|
||||
this,
|
||||
instanceId,
|
||||
cryptoHelper,
|
||||
VMGuid);
|
||||
VMGuid,
|
||||
ConfigurationName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -2070,12 +2081,14 @@ namespace System.Management.Automation.Runspaces
|
||||
internal VMConnectionInfo(
|
||||
PSCredential credential,
|
||||
Guid vmGuid,
|
||||
string vmName)
|
||||
string vmName,
|
||||
string configurationName)
|
||||
: base()
|
||||
{
|
||||
Credential = credential;
|
||||
VMGuid = vmGuid;
|
||||
ComputerName = vmName;
|
||||
ConfigurationName = configurationName;
|
||||
|
||||
AuthenticationMechanism = AuthenticationMechanism.Default;
|
||||
OpenTimeout = _defaultOpenTimeout;
|
||||
@@ -2224,9 +2237,10 @@ namespace System.Management.Automation.Runspaces
|
||||
/// </summary>
|
||||
public static ContainerConnectionInfo CreateContainerConnectionInfoById(
|
||||
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);
|
||||
}
|
||||
@@ -2236,9 +2250,10 @@ namespace System.Management.Automation.Runspaces
|
||||
/// </summary>
|
||||
public static ContainerConnectionInfo CreateContainerConnectionInfoByName(
|
||||
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);
|
||||
}
|
||||
@@ -2277,6 +2292,7 @@ namespace System.Management.Automation.Runspaces
|
||||
private string containerName;
|
||||
private int processId;
|
||||
private bool runAsAdmin = false;
|
||||
private string configurationName;
|
||||
private bool processTerminated = false;
|
||||
private uint errorCode = 0;
|
||||
private string errorMessage = string.Empty;
|
||||
@@ -2339,6 +2355,15 @@ namespace System.Management.Automation.Runspaces
|
||||
set { runAsAdmin = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The configuration name of the container session.
|
||||
/// </summary>
|
||||
internal string ConfigurationName
|
||||
{
|
||||
get { return configurationName; }
|
||||
set { configurationName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the process in container has terminated.
|
||||
/// </summary>
|
||||
@@ -2388,12 +2413,13 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Creates an instance used for PowerShell Direct for container.
|
||||
/// </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.ContainerName = containerName;
|
||||
this.ProcessId = processId;
|
||||
this.RunAsAdmin = runAsAdmin;
|
||||
this.ConfigurationName = configurationName;
|
||||
|
||||
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.
|
||||
//
|
||||
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",
|
||||
String.IsNullOrEmpty(ConfigurationName) ? String.Empty : String.Concat("-Config ", ConfigurationName),
|
||||
(RunAsAdmin) ? "false" : "true");
|
||||
|
||||
//
|
||||
|
||||
@@ -231,6 +231,7 @@ namespace System.Management.Automation.Remoting
|
||||
InvalidContainerNameMultiple = 971,
|
||||
InvalidContainerNameNotExist = 972,
|
||||
ContainerSessionConnectFailed = 973,
|
||||
RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure = 974,
|
||||
|
||||
// Invoke-Command related error codes.
|
||||
InvalidVMIdNotSingle = 981,
|
||||
@@ -698,10 +699,10 @@ namespace System.Management.Automation.Remoting
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This exception is used by PowerShell Direct for credential related error.
|
||||
/// This exception is used by PowerShell Direct errors.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PSDirectCredentialException : RuntimeException
|
||||
public class PSDirectException : RuntimeException
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
@@ -711,7 +712,7 @@ namespace System.Management.Automation.Remoting
|
||||
/// <param name="message">
|
||||
/// A localized string as an error message.
|
||||
/// </param>
|
||||
public PSDirectCredentialException(string message)
|
||||
public PSDirectException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1264,6 +1264,7 @@ namespace System.Management.Automation.Remoting.Client
|
||||
#region Private Data
|
||||
|
||||
private Guid _vmGuid;
|
||||
private string _configurationName;
|
||||
private VMConnectionInfo _connectionInfo;
|
||||
private NetworkCredential _networkCredential;
|
||||
|
||||
@@ -1275,7 +1276,8 @@ namespace System.Management.Automation.Remoting.Client
|
||||
VMConnectionInfo connectionInfo,
|
||||
Guid runspaceId,
|
||||
PSRemotingCryptoHelper cryptoHelper,
|
||||
Guid vmGuid)
|
||||
Guid vmGuid,
|
||||
string configurationName)
|
||||
: base(runspaceId, cryptoHelper)
|
||||
{
|
||||
if (connectionInfo == null)
|
||||
@@ -1285,6 +1287,7 @@ namespace System.Management.Automation.Remoting.Client
|
||||
|
||||
_connectionInfo = connectionInfo;
|
||||
_vmGuid = vmGuid;
|
||||
_configurationName = configurationName;
|
||||
|
||||
if (connectionInfo.Credential == null)
|
||||
{
|
||||
@@ -1307,7 +1310,7 @@ namespace System.Management.Automation.Remoting.Client
|
||||
internal override void CreateAsync()
|
||||
{
|
||||
_client = new RemoteSessionHyperVSocketClient(_vmGuid, true);
|
||||
if (!_client.Connect(_networkCredential, true))
|
||||
if (!_client.Connect(_networkCredential, _configurationName, true))
|
||||
{
|
||||
_client.Dispose();
|
||||
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.
|
||||
_client.Dispose();
|
||||
_client = new RemoteSessionHyperVSocketClient(_vmGuid, false);
|
||||
if (!_client.Connect(_networkCredential, false))
|
||||
if (!_client.Connect(_networkCredential, _configurationName, false))
|
||||
{
|
||||
_client.Dispose();
|
||||
throw new PSInvalidOperationException(
|
||||
@@ -1380,7 +1383,7 @@ namespace System.Management.Automation.Remoting.Client
|
||||
internal override void CreateAsync()
|
||||
{
|
||||
_client = new RemoteSessionHyperVSocketClient(_targetGuid, false, true);
|
||||
if (!_client.Connect(null, false))
|
||||
if (!_client.Connect(null, String.Empty, false))
|
||||
{
|
||||
_client.Dispose();
|
||||
throw new PSInvalidOperationException(
|
||||
@@ -1426,9 +1429,7 @@ namespace System.Management.Automation.Remoting.Client
|
||||
}
|
||||
|
||||
_connectionInfo = connectionInfo;
|
||||
|
||||
_threadName = threadName;
|
||||
|
||||
Fragmentor.FragmentSize = RemoteSessionNamedPipeServer.NamedPipeBufferSizeForRemoting;
|
||||
}
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ namespace System.Management.Automation.Remoting.Server
|
||||
// AppDomain is not available in CoreCLR
|
||||
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomainUnhandledException);
|
||||
#endif
|
||||
SingletonInstance.Start(initialCommand);
|
||||
SingletonInstance.Start(initialCommand, namedPipeServer.ConfigurationName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -480,33 +480,8 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
private readonly Hashtable _helpFiles = new Hashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Finds a help file associated with the given cmdlet
|
||||
/// </summary>
|
||||
/// <param name="cmdletInfo"></param>
|
||||
/// <returns></returns>
|
||||
private string FindHelpFile(CmdletInfo cmdletInfo)
|
||||
private string GetHelpFile(string helpFile, 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;
|
||||
|
||||
// Get the mshsnapinfo object for this cmdlet.
|
||||
@@ -560,6 +535,80 @@ namespace System.Management.Automation
|
||||
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)
|
||||
{
|
||||
Exception e = null;
|
||||
|
||||
@@ -81,6 +81,6 @@
|
||||
},
|
||||
|
||||
"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>
|
||||
</data>
|
||||
<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 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>
|
||||
|
||||
+3
@@ -214,6 +214,9 @@
|
||||
<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>
|
||||
</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">
|
||||
<value>Version specified in ModuleVersion key is equal to version folder name.</value>
|
||||
</data>
|
||||
@@ -921,6 +921,12 @@ Possible matches are</value>
|
||||
<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>
|
||||
</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">
|
||||
<value>Wildcard characters are not supported for module names.</value>
|
||||
</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>
|
||||
</data>
|
||||
<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 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>
|
||||
@@ -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>
|
||||
</data>
|
||||
<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 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>
|
||||
|
||||
+4
-4
@@ -1240,6 +1240,9 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
|
||||
<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>
|
||||
</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">
|
||||
<value>Failed to create an instance of RemoteSessionHyperVSocketServer.</value>
|
||||
</data>
|
||||
@@ -1435,7 +1438,7 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
|
||||
<value>{0}[{1}]: {2}</value>
|
||||
</data>
|
||||
<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 name="WSManPluginConnectNoNegotiationData" xml:space="preserve">
|
||||
<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">
|
||||
<value>Remote transport error: {0}</value>
|
||||
</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">
|
||||
<value>Unable to open pipe connection for PowerShell in container. Error code: {0}.</value>
|
||||
</data>
|
||||
+1
-1
Submodule src/windows-build updated: 4ea0fb9670...e6bf85694a
Reference in New Issue
Block a user