@@ -38,6 +38,7 @@ public class Helper
38
38
private readonly static Version minSupportedPSVersion = new Version ( 3 , 0 ) ;
39
39
private Dictionary < string , Dictionary < string , object > > ruleArguments ;
40
40
private PSVersionTable psVersionTable ;
41
+ private Dictionary < string , CommandInfo > commandInfoCache ;
41
42
42
43
#endregion
43
44
@@ -146,6 +147,7 @@ public void Initialize()
146
147
KeywordBlockDictionary = new Dictionary < String , List < Tuple < int , int > > > ( StringComparer . OrdinalIgnoreCase ) ;
147
148
VariableAnalysisDictionary = new Dictionary < Ast , VariableAnalysis > ( ) ;
148
149
ruleArguments = new Dictionary < string , Dictionary < string , object > > ( StringComparer . OrdinalIgnoreCase ) ;
150
+ commandInfoCache = new Dictionary < string , CommandInfo > ( StringComparer . OrdinalIgnoreCase ) ;
149
151
150
152
IEnumerable < CommandInfo > aliases = this . invokeCommand . GetCommands ( "*" , CommandTypes . Alias , true ) ;
151
153
@@ -610,12 +612,16 @@ public bool HasSplattedVariable(CommandAst cmdAst)
610
612
/// <returns></returns>
611
613
public bool PositionalParameterUsed ( CommandAst cmdAst , bool moreThanThreePositional = false )
612
614
{
613
- if ( cmdAst == null || cmdAst . GetCommandName ( ) == null )
615
+ if ( cmdAst == null )
614
616
{
615
617
return false ;
616
618
}
617
619
618
- CommandInfo commandInfo = GetCommandInfo ( GetCmdletNameFromAlias ( cmdAst . GetCommandName ( ) ) ) ?? GetCommandInfo ( cmdAst . GetCommandName ( ) ) ;
620
+ var commandInfo = GetCommandInfo ( cmdAst . GetCommandName ( ) ) ;
621
+ if ( commandInfo == null || ( commandInfo . CommandType != System . Management . Automation . CommandTypes . Cmdlet ) )
622
+ {
623
+ return false ;
624
+ }
619
625
620
626
IEnumerable < ParameterMetadata > switchParams = null ;
621
627
@@ -685,6 +691,23 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio
685
691
}
686
692
687
693
694
+ /// <summary>
695
+ /// Get a CommandInfo object of the given command name
696
+ /// </summary>
697
+ /// <returns>Returns null if command does not exists</returns>
698
+ private CommandInfo GetCommandInfoInternal ( string cmdName , CommandTypes ? commandType = null )
699
+ {
700
+ using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
701
+ {
702
+ var cmdInfo = ps . AddCommand ( "Get-Command" )
703
+ . AddArgument ( cmdName )
704
+ . AddParameter ( "ErrorAction" , "SilentlyContinue" )
705
+ . Invoke < CommandInfo > ( )
706
+ . FirstOrDefault ( ) ;
707
+ return cmdInfo ;
708
+ }
709
+ }
710
+
688
711
/// <summary>
689
712
/// Given a command's name, checks whether it exists
690
713
/// </summary>
@@ -693,19 +716,28 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio
693
716
/// <returns></returns>
694
717
public CommandInfo GetCommandInfo ( string name , CommandTypes ? commandType = null )
695
718
{
696
- CommandTypes defaultCmdType = CommandTypes . Alias
697
- | CommandTypes . Cmdlet
698
- | CommandTypes . ExternalScript
699
- | CommandTypes . Filter
700
- | CommandTypes . Function
701
- | CommandTypes . Script
702
- | CommandTypes . Workflow ;
703
- #if ! PSV3
704
- defaultCmdType |= CommandTypes . Configuration ;
705
- #endif
719
+ if ( string . IsNullOrWhiteSpace ( name ) )
720
+ {
721
+ return null ;
722
+ }
723
+
724
+ // check if it is an alias
725
+ string cmdletName = Helper . Instance . GetCmdletNameFromAlias ( name ) ;
726
+ if ( string . IsNullOrWhiteSpace ( cmdletName ) )
727
+ {
728
+ cmdletName = name ;
729
+ }
730
+
706
731
lock ( getCommandLock )
707
732
{
708
- return this . invokeCommand . GetCommand ( name , commandType ?? defaultCmdType ) ;
733
+ if ( commandInfoCache . ContainsKey ( cmdletName ) )
734
+ {
735
+ return commandInfoCache [ cmdletName ] ;
736
+ }
737
+
738
+ var commandInfo = GetCommandInfoInternal ( cmdletName , commandType ) ;
739
+ commandInfoCache . Add ( cmdletName , commandInfo ) ;
740
+ return commandInfo ;
709
741
}
710
742
}
711
743
0 commit comments