Had to rewrite this post with the actual code since there must be some kind of difference with binary modules.
The full cmdlet is as follows (apologies for length):
In a nutshell, this function basically uses the SMO library and pulls information about a database users from a SQL Server Instance.
namespace Namespace
{
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using static PrivateFunctions;
[Cmdlet(VerbsCommon.Get, "DatabaseUserInformation")]
public class GetDatabaseUserInformationCmdlet : PSCmdlet
{
[Parameter(Mandatory = true,
HelpMessage = "The user name of the account to retrieve information for.",
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
public string LogonName { get; set; }
private List<object> userInformation = new List<object>();
protected override void ProcessRecord()
{
string samAccountName = GetSamAccountName(LogonName);
Login login = null;
User user = null;
WriteVerbose($"Getting login for account: {samAccountName}...");
try
{
login = GetLogin(samAccountName);
}
catch (InvalidOperationException invalidOperation)
{
ThrowTerminatingError(new ErrorRecord(
invalidOperation,
"LoginNotFound",
ErrorCategory.InvalidOperation,
login));
}
WriteVerbose($"Getting user for login: {login.Name}...");
try
{
user = GetUser(login);
}
catch (InvalidOperationException invalidOperation)
{
ThrowTerminatingError(new ErrorRecord(
invalidOperation,
"UserNotFound",
ErrorCategory.InvalidOperation,
user));
}
WriteVerbose($"Gathering information for user: {user.Name}");
var information = new
{
LoginName = login.Name,
UserName = user.Name,
FullAccess = TestFullAccessOnDatabase(user),
Roles = user.EnumRoles()
};
userInformation.Add(information);
}
protected override void EndProcessing()
{
WriteVerbose("Writing information to output.");
userInformation.ForEach(item => WriteObject(item));
}
}
}
The cmdlet can be used with a single argument:
Get-DatabaseUserInformation user1
Or I also want to be able to pipe an array to it when dealing with multiple users.
@('user1', 'user2','user3') | Get-DatabaseUserInformation
If I'm using a single value and that user doesn't exist, then fair enough, it terminates, and it's a case of correcting it and running it again.
But when I'm using it with multiple values, if one of them doesn't exist, it doesn't give any output as all, only the exception.
So the output I get when everything is OK is something like this (with verbose on):
VERBOSE: Getting login for account: DOMAIN\user1...
VERBOSE: Getting user for login: DOMAIN\user1...
VERBOSE: Gathering information for user: dbo
VERBOSE: Getting login for account: DOMAIN\user2...
VERBOSE: Getting user for login: DOMAIN\user2...
VERBOSE: Gathering information for user: user2
VERBOSE: Getting login for account: DOMAIN\user3...
VERBOSE: Getting user for login: DOMAIN\user3...
VERBOSE: Gathering information for user: user3
VERBOSE: Writing information to output.
LoginName UserName FullAccess Roles
--------- -------- ---------- -----
DOMAIN\user1 dbo True {db_owner}
DOMAIN\user2 user2 False {role1}
DOMAIN\user3 user3 False {}
What I get when something is wrong: (in this case, user2 has been misspelt.)
Get-DatabaseUserInformation : A login for the account 'DOMAIN\usr2' does not
exist in the database.
At line:1 char:6
+ $x | Get-DatabaseUserInformation -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-DatabaseUserInformation], InvalidOperationException
+ FullyQualifiedErrorId : LoginNotFound,DatabaseUserManagement.GetDatabase
UserInformationCmdlet
What I want to happen is something similar to this.
VERBOSE: Getting login for account: DOMAIN\user1...
VERBOSE: Getting user for login: DOMAIN\user1...
VERBOSE: Gathering information for user: dbo
VERBOSE: Getting login for account: DOMAIN\usr2...
Get-DatabaseUserInformation : A login for the account 'DOMAIN\usr2' does not
exist in the database.
At line:1 char:6
+ $x | Get-DatabaseUserInformation -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-DatabaseUserInformation], InvalidOperationException
+ FullyQualifiedErrorId : LoginNotFound,DatabaseUserManagement.GetDatabase
UserInformationCmdlet
VERBOSE: Getting login for account: DOMAIN\user3...
VERBOSE: Getting user for login: DOMAIN\user3...
VERBOSE: Gathering information for user: user3
VERBOSE: Writing information to output.
LoginName UserName FullAccess Roles
--------- -------- ---------- -----
DOMAIN\user1 dbo True {db_owner}
DOMAIN\user3 user3 False {}