I've written code to be called from Powershell like so:
Rename-DatabaseUser -Name 'someuser' -NewName 'somenewuser'
I'm wondering if there's another way I can approach this. I want to create objects of the same type with slightly differing property values.
Here's the code I'm currently using now (RenameDatabaseUserCmdlet.cs):
namespace Company.Powershell.Module.Cmdlets
{
using System.Management.Automation;
[Cmdlet(VerbsCommon.Rename, "DatabaseUser")]
[Alias("rndbu")]
public class RenameDatabaseUserCmdlet : PSCmdlet
{
[Parameter(ParameterSetName = "Object")]
public DatabaseUser User { get; set; }
[Parameter(ParameterSetName = "String")]
public string Name { get; set; }
[Parameter(ParameterSetName = "Object")]
[Parameter(ParameterSetName = "String")]
public string NewName { get; set; }
protected override void ProcessRecord()
{
DatabaseUser user;
if (ParameterSetName == "String")
{
var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);
ps.AddCommand("Get-DatabaseUser")
.AddParameter("Name", Name);
foreach (var result in ps.Invoke())
{
user = result?.BaseObject as DatabaseUser;
if (user == null)
{
// This is where I'm not sure I'm doing it right.
WriteError(DatabaseErrorRecord.UserNotFound(Name));
return;
}
}
}
else
{
user = User;
}
// Still more to do here...
}
}
}
This is how I create the objects. In DatabaseErrorRecord
I have multiple static methods which return an ErrorRecord
object initialised slightly differently. These are some of the methods:
namespace Company.Powershell.Module
{
using System;
using System.Management.Automation;
class DatabaseErrorRecord : ErrorRecord
{
// This is added just so it compiles, which is why I think I'm wrong.
private DatabaseErrorRecord(Exception exception,
string errorId,
ErrorCategory errorCategory,
object targetObject) : base(exception, errorId, errorCategory, targetObject)
{ }
public static ErrorRecord UserNotFound(string userName)
{
return new ErrorRecord
(
new NullReferenceException($"The user '{userName}' could not be found in the database."),
"UserNotFound",
ErrorCategory.ObjectNotFound,
null
);
}
public static ErrorRecord DatabaseNotFound(string databaseName)
{
return new ErrorRecord
(
new NullReferenceException($"The database '{databaseName}' could not be found on the SQL Server instance."),
"DatabaseNotFound",
ErrorCategory.ObjectNotFound,
null
);
}
public static ErrorRecord PermissionConflict(string permissionA, string permissionB)
{
return new ErrorRecord
(
new InvalidOperationException($"Granting {permissionA} to this user would cause a conflict with {permissionB}."),
"PermissionConflict",
ErrorCategory.InvalidOperation,
null
);
}
// Other methods omitted...
}
}
What is a good way to create objects of the same type, using slightly different arguments?
In each of these methods, when the ErrorRecord
is created. The Exception, Error ID and Error Category will all be different. I would create these objects when I need them in code, but there's some instances where I would need the same object twice.
I'm still thinking this is wrong since I have to include the constructor despite the fact I will never use it.
Is there any other ways I could structure this?