/// <summary> /// Resolve all wildcards in user input Property into resolvedNameMshParameters. /// </summary> private void InitializeResolvedNameMshParameters() { // temp list of properties with wildcards resolved var resolvedNameProperty = new List <object>(); foreach (MshParameter p in _propertyMshParameterList) { string label = p.GetEntry(ConvertHTMLParameterDefinitionKeys.LabelEntryKey) as string; string alignment = p.GetEntry(ConvertHTMLParameterDefinitionKeys.AlignmentEntryKey) as string; // Accept the width both as a string and as an int. string width; int? widthNum = p.GetEntry(ConvertHTMLParameterDefinitionKeys.WidthEntryKey) as int?; width = widthNum != null?widthNum.Value.ToString() : p.GetEntry(ConvertHTMLParameterDefinitionKeys.WidthEntryKey) as string; PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; List <PSPropertyExpression> resolvedNames = ex.ResolveNames(_inputObject); foreach (PSPropertyExpression resolvedName in resolvedNames) { Hashtable ht = CreateAuxPropertyHT(label, alignment, width); if (resolvedName.Script != null) { // The argument is a calculated property whose value is calculated by a script block. ht.Add(FormatParameterDefinitionKeys.ExpressionEntryKey, resolvedName.Script); } else { ht.Add(FormatParameterDefinitionKeys.ExpressionEntryKey, resolvedName.ToString()); } resolvedNameProperty.Add(ht); } } _resolvedNameMshParameters = ProcessParameter(resolvedNameProperty.ToArray()); }
// Expand a list of (possibly wildcarded) expressions into resolved expressions that // match property names on the incoming objects. private static void ExpandExpressions(PSObject inputObject, List <MshParameter> UnexpandedParametersWithWildCardPattern, List <MshParameter> expandedParameterList) { if (UnexpandedParametersWithWildCardPattern != null) { foreach (MshParameter unexpandedParameter in UnexpandedParametersWithWildCardPattern) { PSPropertyExpression ex = (PSPropertyExpression)unexpandedParameter.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey); SortedDictionary <string, PSPropertyExpression> expandedPropertyNames = new SortedDictionary <string, PSPropertyExpression>(StringComparer.OrdinalIgnoreCase); if (inputObject == null) { continue; } foreach (PSPropertyExpression resolvedName in ex.ResolveNames(PSObject.AsPSObject(inputObject))) { expandedPropertyNames[resolvedName.ToString()] = resolvedName; } foreach (PSPropertyExpression expandedExpression in expandedPropertyNames.Values) { MshParameter expandedParameter = new MshParameter(); expandedParameter.hash = (Hashtable)unexpandedParameter.hash.Clone(); expandedParameter.hash[FormatParameterDefinitionKeys.ExpressionEntryKey] = expandedExpression; expandedParameterList.Add(expandedParameter); } } } }
/// <summary> /// Gets the values of the object properties matched by this expression. /// </summary> /// <param name="target">The object to match against.</param> /// <param name="expand">If the matched properties are parameter sets, expand them.</param> /// <param name="eatExceptions">If true, any exceptions that occur during the match process are ignored.</param> public List <PSPropertyExpressionResult> GetValues(PSObject target, bool expand, bool eatExceptions) { List <PSPropertyExpressionResult> retVal = new List <PSPropertyExpressionResult>(); // If the object passed in is a hashtable, then turn it into a PSCustomObject so // that property expressions can work on it. target = IfHashtableWrapAsPSCustomObject(target); // process the script case if (Script != null) { PSPropertyExpression scriptExpression = new PSPropertyExpression(Script); PSPropertyExpressionResult r = scriptExpression.GetValue(target, eatExceptions); retVal.Add(r); return(retVal); } // process the expression List <PSPropertyExpression> resolvedExpressionList = this.ResolveNames(target, expand); foreach (PSPropertyExpression re in resolvedExpressionList) { PSPropertyExpressionResult r = re.GetValue(target, eatExceptions); retVal.Add(r); } return(retVal); }
/// <summary> /// Try to match the expression against the array of wildcard patterns. /// The first match shortcircuits the search. /// </summary> /// <param name="expression">PSPropertyExpression to test against.</param> /// <returns>True if there is a match, else false.</returns> internal bool IsMatch(PSPropertyExpression expression) { for (int k = 0; k < _wildcardPatterns.Length; k++) { if (_wildcardPatterns[k].IsMatch(expression.ToString())) return true; } return false; }
/// <summary> /// To write the Property name. /// </summary> private static void WritePropertyName(StringBuilder Listtag, MshParameter p) { // for writing the property name string label = p.GetEntry(ConvertHTMLParameterDefinitionKeys.LabelEntryKey) as string; if (label != null) { Listtag.Append(label); } else { PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; Listtag.Append(ex.ToString()); } }
// Expand a list of (possibly wildcarded) expressions into resolved expressions that // match property names on the incoming objects. private static List <MshParameter> ExpandExpressions(List <PSObject> inputObjects, List <MshParameter> unexpandedParameterList) { List <MshParameter> expandedParameterList = new List <MshParameter>(); if (unexpandedParameterList != null) { foreach (MshParameter unexpandedParameter in unexpandedParameterList) { PSPropertyExpression ex = (PSPropertyExpression)unexpandedParameter.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey); if (!ex.HasWildCardCharacters) // this special cases 1) script blocks and 2) wildcard-less strings { expandedParameterList.Add(unexpandedParameter); } else { SortedDictionary <string, PSPropertyExpression> expandedPropertyNames = new SortedDictionary <string, PSPropertyExpression>(StringComparer.OrdinalIgnoreCase); if (inputObjects != null) { foreach (object inputObject in inputObjects) { if (inputObject == null) { continue; } foreach (PSPropertyExpression resolvedName in ex.ResolveNames(PSObject.AsPSObject(inputObject))) { expandedPropertyNames[resolvedName.ToString()] = resolvedName; } } } foreach (PSPropertyExpression expandedExpression in expandedPropertyNames.Values) { MshParameter expandedParameter = new MshParameter(); expandedParameter.hash = (Hashtable)unexpandedParameter.hash.Clone(); expandedParameter.hash[FormatParameterDefinitionKeys.ExpressionEntryKey] = expandedExpression; expandedParameterList.Add(expandedParameter); } } } } return(expandedParameterList); }
private static void EvaluateSortingExpression( MshParameter p, PSObject inputObject, List <ObjectCommandPropertyValue> orderValues, List <ErrorRecord> errors, out string propertyNotFoundMsg, ref bool comparable) { // NOTE: we assume globbing was not allowed in input PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; // get the values, but do not expand aliases List <PSPropertyExpressionResult> expressionResults = ex.GetValues(inputObject, false, true); if (expressionResults.Count == 0) { // we did not get any result out of the expression: // we enter a null as a place holder orderValues.Add(ObjectCommandPropertyValue.NonExistingProperty); propertyNotFoundMsg = StringUtil.Format(SortObjectStrings.PropertyNotFound, ex.ToString()); return; } propertyNotFoundMsg = null; // we obtained some results, enter them into the list foreach (PSPropertyExpressionResult r in expressionResults) { if (r.Exception == null) { orderValues.Add(new ObjectCommandPropertyValue(r.Result)); } else { ErrorRecord errorRecord = new ErrorRecord( r.Exception, "ExpressionEvaluation", ErrorCategory.InvalidResult, inputObject); errors.Add(errorRecord); orderValues.Add(ObjectCommandPropertyValue.ExistingNullProperty); } comparable = true; } }
/// <summary> /// Gets the values of the object properties matched by this expression. /// </summary> /// <param name="target">The object to match against.</param> /// <param name="expand">If the matched properties are parameter sets, expand them.</param> /// <param name="eatExceptions">If true, any exceptions that occur during the match process are ignored.</param> public List <PSPropertyExpressionResult> GetValues(PSObject target, bool expand, bool eatExceptions) { List <PSPropertyExpressionResult> retVal = new List <PSPropertyExpressionResult>(); // process the script case if (Script != null) { PSPropertyExpression scriptExpression = new PSPropertyExpression(Script); PSPropertyExpressionResult r = scriptExpression.GetValue(target, eatExceptions); retVal.Add(r); return(retVal); } foreach (PSPropertyExpression resolvedName in ResolveNames(target, expand)) { PSPropertyExpressionResult result = resolvedName.GetValue(target, eatExceptions); retVal.Add(result); } return(retVal); }
/// <summary> /// Resolve all wildcards in user input Property into resolvedNameMshParameters. /// </summary> private void InitializeResolvedNameMshParameters() { // temp list of properties with wildcards resolved ArrayList resolvedNameProperty = new ArrayList(); foreach (MshParameter p in _propertyMshParameterList) { string label = p.GetEntry(ConvertHTMLParameterDefinitionKeys.LabelEntryKey) as string; string alignment = p.GetEntry(ConvertHTMLParameterDefinitionKeys.AlignmentEntryKey) as string; string width = p.GetEntry(ConvertHTMLParameterDefinitionKeys.WidthEntryKey) as string; PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; List <PSPropertyExpression> resolvedNames = ex.ResolveNames(_inputObject); foreach (PSPropertyExpression resolvedName in resolvedNames) { Hashtable ht = CreateAuxPropertyHT(label, alignment, width); ht.Add(FormatParameterDefinitionKeys.ExpressionEntryKey, resolvedName.ToString()); resolvedNameProperty.Add(ht); } } _resolvedNameMshParameters = ProcessParameter(resolvedNameProperty.ToArray()); }
/// <summary> /// To write the Property value. /// </summary> private void WritePropertyValue(StringBuilder Listtag, MshParameter p) { PSPropertyExpression exValue = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; // get the value of the property List <PSPropertyExpressionResult> resultList = exValue.GetValues(_inputObject); foreach (PSPropertyExpressionResult result in resultList) { // create comma sep list for multiple results if (result.Result != null) { string htmlEncodedResult = WebUtility.HtmlEncode(SafeToString(result.Result)); Listtag.Append(htmlEncodedResult); } Listtag.Append(", "); } if (Listtag.ToString().EndsWith(", ", StringComparison.Ordinal)) { Listtag.Remove(Listtag.Length - 2, 2); } }
internal void ProcessExpressionParameter( PSCmdlet cmdlet, object[] expr) { TerminatingErrorContext invocationContext = new TerminatingErrorContext(cmdlet); // compare-object and group-object use the same definition here ParameterProcessor processor = cmdlet is SortObjectCommand ? new ParameterProcessor(new SortObjectExpressionParameterDefinition()) : new ParameterProcessor(new GroupObjectExpressionParameterDefinition()); if (expr != null) { if (_unexpandedParameterList == null) { _unexpandedParameterList = processor.ProcessParameters(expr, invocationContext); foreach (MshParameter unexpandedParameter in _unexpandedParameterList) { PSPropertyExpression mshExpression = (PSPropertyExpression)unexpandedParameter.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey); if (!mshExpression.HasWildCardCharacters) // this special cases 1) script blocks and 2) wildcard-less strings { _mshParameterList.Add(unexpandedParameter); } else { if (_unExpandedParametersWithWildCardPattern == null) { _unExpandedParametersWithWildCardPattern = new List <MshParameter>(); } _unExpandedParametersWithWildCardPattern.Add(unexpandedParameter); } } } } }
private void ProcessExpandParameter(MshParameter p, PSObject inputObject, List <PSNoteProperty> matchedProperties) { PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; List <PSPropertyExpressionResult> expressionResults = ex.GetValues(inputObject); if (expressionResults.Count == 0) { ErrorRecord errorRecord = new( PSTraceSource.NewArgumentException("ExpandProperty", SelectObjectStrings.PropertyNotFound, ExpandProperty), "ExpandPropertyNotFound", ErrorCategory.InvalidArgument, inputObject); throw new SelectObjectException(errorRecord); } if (expressionResults.Count > 1) { ErrorRecord errorRecord = new( PSTraceSource.NewArgumentException("ExpandProperty", SelectObjectStrings.MutlipleExpandProperties, ExpandProperty), "MutlipleExpandProperties", ErrorCategory.InvalidArgument, inputObject); throw new SelectObjectException(errorRecord); } PSPropertyExpressionResult r = expressionResults[0]; if (r.Exception == null) { // ignore the property value if it's null if (r.Result == null) { return; } System.Collections.IEnumerable results = LanguagePrimitives.GetEnumerable(r.Result); if (results == null) { // add NoteProperties if there is any // If r.Result is a base object, we don't want to associate the NoteProperty // directly with it. We want the NoteProperty to be associated only with this // particular PSObject, so that when the user uses the base object else where, // its members remain the same as before the Select-Object command run. PSObject expandedObject = PSObject.AsPSObject(r.Result, true); AddNoteProperties(expandedObject, inputObject, matchedProperties); FilteredWriteObject(expandedObject, matchedProperties); return; } foreach (object expandedValue in results) { // ignore the element if it's null if (expandedValue == null) { continue; } // add NoteProperties if there is any // If expandedValue is a base object, we don't want to associate the NoteProperty // directly with it. We want the NoteProperty to be associated only with this // particular PSObject, so that when the user uses the base object else where, // its members remain the same as before the Select-Object command run. PSObject expandedObject = PSObject.AsPSObject(expandedValue, true); AddNoteProperties(expandedObject, inputObject, matchedProperties); FilteredWriteObject(expandedObject, matchedProperties); } } else { ErrorRecord errorRecord = new( r.Exception, "PropertyEvaluationExpand", ErrorCategory.InvalidResult, inputObject); throw new SelectObjectException(errorRecord); } }
/// <summary> /// Create a property expression result containing the original object, matching property expression /// and any exception generated during the match process. /// </summary> public PSPropertyExpressionResult(object res, PSPropertyExpression re, Exception e) { Result = res; ResolvedExpression = re; Exception = e; }
/// <summary> /// Resolve the names matched by this the expression. /// </summary> /// <param name="target">The object to apply the expression against.</param> /// <param name="expand">If the matched properties are property sets, expand them.</param> public List <PSPropertyExpression> ResolveNames(PSObject target, bool expand) { List <PSPropertyExpression> retVal = new List <PSPropertyExpression>(); if (_isResolved) { retVal.Add(this); return(retVal); } if (Script != null) { // script block, just add it to the list and be done PSPropertyExpression ex = new PSPropertyExpression(Script); ex._isResolved = true; retVal.Add(ex); return(retVal); } // If the object passed in is a hashtable, then turn it into a PSCustomObject so // that property expressions can work on it. target = IfHashtableWrapAsPSCustomObject(target); // we have a string value IEnumerable <PSMemberInfo> members = null; if (HasWildCardCharacters) { // get the members first: this will expand the globbing on each parameter members = target.Members.Match(_stringValue, PSMemberTypes.Properties | PSMemberTypes.PropertySet | PSMemberTypes.Dynamic); } else { // we have no globbing: try an exact match, because this is quicker. PSMemberInfo x = target.Members[_stringValue]; if ((x == null) && (target.BaseObject is System.Dynamic.IDynamicMetaObjectProvider)) { // We could check if GetDynamicMemberNames includes the name... but // GetDynamicMemberNames is only a hint, not a contract, so we'd want // to attempt the binding whether it's in there or not. x = new PSDynamicMember(_stringValue); } List <PSMemberInfo> temp = new List <PSMemberInfo>(); if (x != null) { temp.Add(x); } members = temp; } // we now have a list of members, we have to expand property sets // and remove duplicates List <PSMemberInfo> temporaryMemberList = new List <PSMemberInfo>(); foreach (PSMemberInfo member in members) { // it can be a property set PSPropertySet propertySet = member as PSPropertySet; if (propertySet != null) { if (expand) { // NOTE: we expand the property set under the // assumption that it contains property names that // do not require any further expansion Collection <string> references = propertySet.ReferencedPropertyNames; for (int j = 0; j < references.Count; j++) { ReadOnlyPSMemberInfoCollection <PSPropertyInfo> propertyMembers = target.Properties.Match(references[j]); for (int jj = 0; jj < propertyMembers.Count; jj++) { temporaryMemberList.Add(propertyMembers[jj]); } } } } // it can be a property else if (member is PSPropertyInfo) { temporaryMemberList.Add(member); } // it can be a dynamic member else if (member is PSDynamicMember) { temporaryMemberList.Add(member); } } Hashtable hash = new Hashtable(); // build the list of unique values: remove the possible duplicates // from property set expansion foreach (PSMemberInfo m in temporaryMemberList) { if (!hash.ContainsKey(m.Name)) { PSPropertyExpression ex = new PSPropertyExpression(m.Name); ex._isResolved = true; retVal.Add(ex); hash.Add(m.Name, null); } } return(retVal); }
internal ExpressionColumnInfo(string staleObjectPropertyName, string displayName, PSPropertyExpression expression) : base(staleObjectPropertyName, displayName) { _expression = expression; }
private void ProcessParameter(MshParameter p, PSObject inputObject, List <PSNoteProperty> result) { string name = p.GetEntry(NameEntryDefinition.NameEntryKey) as string; PSPropertyExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as PSPropertyExpression; List <PSPropertyExpressionResult> expressionResults = new(); foreach (PSPropertyExpression resolvedName in ex.ResolveNames(inputObject)) { if (_exclusionFilter == null || !_exclusionFilter.IsMatch(resolvedName)) { List <PSPropertyExpressionResult> tempExprResults = resolvedName.GetValues(inputObject); if (tempExprResults == null) { continue; } foreach (PSPropertyExpressionResult mshExpRes in tempExprResults) { expressionResults.Add(mshExpRes); } } } // allow 'Select-Object -Property noexist-name' to return a PSObject with property noexist-name, // unless noexist-name itself contains wildcards if (expressionResults.Count == 0 && !ex.HasWildCardCharacters) { expressionResults.Add(new PSPropertyExpressionResult(null, ex, null)); } // if we have an expansion, renaming is not acceptable else if (!string.IsNullOrEmpty(name) && expressionResults.Count > 1) { string errorMsg = SelectObjectStrings.RenamingMultipleResults; ErrorRecord errorRecord = new( new InvalidOperationException(errorMsg), "RenamingMultipleResults", ErrorCategory.InvalidOperation, inputObject); WriteError(errorRecord); return; } foreach (PSPropertyExpressionResult r in expressionResults) { // filter the exclusions, if any if (_exclusionFilter != null && _exclusionFilter.IsMatch(r.ResolvedExpression)) { continue; } PSNoteProperty mshProp; if (string.IsNullOrEmpty(name)) { string resolvedExpressionName = r.ResolvedExpression.ToString(); if (string.IsNullOrEmpty(resolvedExpressionName)) { PSArgumentException mshArgE = PSTraceSource.NewArgumentException( "Property", SelectObjectStrings.EmptyScriptBlockAndNoName); ThrowTerminatingError( new ErrorRecord( mshArgE, "EmptyScriptBlockAndNoName", ErrorCategory.InvalidArgument, null)); } mshProp = new PSNoteProperty(resolvedExpressionName, r.Result); } else { mshProp = new PSNoteProperty(name, r.Result); } result.Add(mshProp); } }
internal HeaderInfo GenerateHeaderInfo(PSObject input, TableControlBody tableBody, OutGridViewCommand parentCmdlet) { HeaderInfo headerInfo = new HeaderInfo(); // This verification is needed because the database returns "LastWriteTime" value for file system objects // as strings and it is used to detect this situation and use the actual field value. bool fileSystemObject = typeof(FileSystemInfo).IsInstanceOfType(input.BaseObject); if (tableBody != null) // If the tableBody is null, the TableControlBody info was not put into the database. { // Generate HeaderInfo from the type information database. List <TableRowItemDefinition> activeRowItemDefinitionList = GetActiveTableRowDefinition(tableBody, input); int col = 0; foreach (TableRowItemDefinition rowItem in activeRowItemDefinitionList) { ColumnInfo columnInfo = null; string displayName = null; TableColumnHeaderDefinition colHeader = null; // Retrieve a matching TableColumnHeaderDefinition if (col < tableBody.header.columnHeaderDefinitionList.Count) { colHeader = tableBody.header.columnHeaderDefinitionList[col]; } if (colHeader != null && colHeader.label != null) { displayName = _typeInfoDatabase.displayResourceManagerCache.GetTextTokenString(colHeader.label); } FormatToken token = null; if (rowItem.formatTokenList.Count > 0) { token = rowItem.formatTokenList[0]; } if (token != null) { FieldPropertyToken fpt = token as FieldPropertyToken; if (fpt != null) { if (displayName == null) { // Database does not provide a label(DisplayName) for the current property, use the expression value instead. displayName = fpt.expression.expressionValue; } if (fpt.expression.isScriptBlock) { PSPropertyExpression ex = _expressionFactory.CreateFromExpressionToken(fpt.expression); // Using the displayName as a propertyName for a stale PSObject. const string LastWriteTimePropertyName = "LastWriteTime"; // For FileSystem objects "LastWriteTime" property value should be used although the database indicates that a script should be executed to get the value. if (fileSystemObject && displayName.Equals(LastWriteTimePropertyName, StringComparison.OrdinalIgnoreCase)) { columnInfo = new OriginalColumnInfo(displayName, displayName, LastWriteTimePropertyName, parentCmdlet); } else { columnInfo = new ExpressionColumnInfo(displayName, displayName, ex); } } else { columnInfo = new OriginalColumnInfo(fpt.expression.expressionValue, displayName, fpt.expression.expressionValue, parentCmdlet); } } else { TextToken tt = token as TextToken; if (tt != null) { displayName = _typeInfoDatabase.displayResourceManagerCache.GetTextTokenString(tt); columnInfo = new OriginalColumnInfo(tt.text, displayName, tt.text, parentCmdlet); } } } if (columnInfo != null) { headerInfo.AddColumn(columnInfo); } col++; } } return(headerInfo); }