I'm writing a binary PowerShell module and have recently started to add wildcard support to some cmdlets.
I'm not sure if I'm using an efficient way of creating the final collection of objects to write back to the pipeline.
I'm wondering if it might be slightly more efficient to use a HashSet<T>
rather than a List<T>
in this case, even though I've been told that Contains()
doesn't have a large overhead on small collections (the final collection would can contain anywhere from 0 to ~25 elements).
Is List<T>
appropriate in this case or should I try and use a HashSet<T>
instead?
[Cmdlet(VerbsCommon.Get, "DatabaseUser")]
[Alias("gdbu")]
[OutputType(new Type[] { typeof(User)})]
public class GetDatabaseUserCmdlet : PSCmdlet
{
[Parameter(ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ValueFromRemainingArguments = true)]
public string[] Name { get; set; }
[Parameter]
public SwitchParameter IncludeSystemAccounts{ get; set; }
List<User> _users = new List<User>();
Hashtable _privateData;
Server _server;
Database _database;
protected override void BeginProcessing()
{
_privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
_server = new Server((string)_privateData["Server"]);
_database = _server.Databases[(string)_privateData["Database"]];
}
protected override void ProcessRecord()
{
var users = _database.Users.Cast<User>();
if(IncludeSystemAccounts.IsPresent == false)
{
users = users.Where(user => user.IsSystemObject == false);
}
if (Name == null)
{
_users = users.ToList();
}
else
{
foreach(var item in Name)
{
var wildcard = new WildcardPattern(item, WildcardOptions.IgnoreCase);
var result = users.Where(user => wildcard.IsMatch(user.Name));
if(result != null)
{
foreach(var user in result)
{
if(_users.Contains(user) == false)
{
_users.Add(user);
}
}
}
}
}
}
protected override void EndProcessing()
{
WriteObject(_users);
}
}
To give an example of how this cmdlet functions. Assume my database has 10 users: named User1 through User10 (not counting dbo, sys, etc.).
If I call the cmdlet like so:
Get-DatabaseUser -Name user[135], user[2-4] | Format-Table -Property Name
This is the expected (and actual result):
Name ---- User1 User3 User5 User2 User4