classes/Credentials.ps1
enum AccountType { Empty = 0 Vault = 1 Domain = 2 Windows = 4 SQL = 8 Generic = 16 } Class Credential { <# # Abstract Class: Credential # Create an Abstract credential class to serve as the interface. # Constructor restricts this class being instantiated directly. #> #Properties hidden [pscredential]$_Credential [string]$Domain [string]$Username [securestring]$Password [bool]$IsValid #region Constructor Methods hidden Init() { $this | Add-Member -Name "Domain" -MemberType ScriptProperty -Value { return $("LDAP://" + ([ADSI]"").distinguishedName) } -Force $this | Add-Member -Name "Username" -MemberType ScriptProperty -Value { return [string]$this._Credential.UserName } -Force $this | Add-Member -Name "Password" -MemberType ScriptProperty -Value { return [securestring]$this._Credential.Password } -Force $this | Add-Member -Name "IsValid" -MemberType ScriptProperty -Value { if ([pscredential]::Empty -eq $this._Credential) { return $false } return [bool]((New-Object DirectoryServices.DirectoryEntry($this.Domain,$this._Credential.UserName,$this._Credential.GetNetworkCredential().Password)).distinguishedName) } -Force } Credential() { # $type = $this.GetType() # if ($type -eq [Credential]) { # throw("Class $type must be inherited") # } $this.Init() $this.Clear() } Credential([pscredential]$Credential) { $this.Init() $this.Set((if ($null -eq $Credential) { [pscredential]::Empty } else { $Credential })) } #endregion Constructor Methods #region Class Methods hidden [string] GetPassword() { return $this._Credential.GetNetworkCredential().Password } [void]Set() { $this._Credential = (Get-Credential -Message "Enter Your Credentials") } [void]Set([string]$Username) { $this._Credential = (Get-Credential -Message "Enter Your Credentials" -UserName $Username) } [void]Set([pscredential]$Credential) { $this._Credential = $Credential [bool]$tmpIsValid = $false if($null -ne $Credential-and [pscredential]::Empty -ne $Credential) { $tmpIsValid = $null -ne ([ADSI]::new($this.Domain, $this.UserName, $this.GetPassword())) if($false -eq $tmpIsValid) { Write-Warning "Credentials Invalid. Please verify your account username and password.`n`n" $this._Credential = [pscredential]::Empty } else { Write-Verbose "Credential Validated. Creating credential object with username and password" $this._Credential = $Credential } } else { Write-Verbose "Credential dialog cancelled or empty value provided. Creating pscredential object with empty value" $this._Credential = [pscredential]::Empty } #Implement Credential testing for different credential types. } [void] Clear() { $this._Credential = [pscredential]::Empty } #endregion Class Methods } class Account : Credential { <# Class Comments .SYNOPSIS Represents a checked out password vault type of account .DESCRIPTION When checking out accounts from password vaults this class will assist with putting the right properties forward. .INPUTS None. You cannot pipe objects to this class. .OUTPUTS Class object with the methods and interface propwerties to represent a checked out vault account eg. VaultAccount .EXAMPLE C:\PS> extension -name "File" File.txt .EXAMPLE C:\PS> extension -name "File" -extension "doc" File.doc .EXAMPLE C:\PS> extension "File" "doc" File.doc .LINK https://github.com/taalmahret/enterprisecommander #> #region Property Declarations hidden [string]$_ID hidden [string]$_AccountName hidden [AccountType]$_AccountType [string]$ID [string]$AccountName [AccountType]$AccountType #endregion Property Declarations #region Class Constructors hidden [void] Init() { Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'ID' -Value { return $this._ID } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'AccountName' -Value { return $this._AccountName } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'AccountType' -Value { return $this._AccountType } ([Credential]$this).Init() } Account() { $this.Init() $this.Clear() } #endregion Class Constructor #region Class Methods [void] Set() { $this._ID = (Read-Host -Prompt 'Input account ID') $this._AccountName = (Read-Host -Prompt 'Input account name') $this._AccountType = [AccountType]::Generic ([Credential]$this).Set() } [void] Set([string]$AccountID, [string]$AccountName, [AccountType]$AccountType) { $this._ID = $AccountID $this._AccountName = $AccountName $this._AccountType = $AccountType switch ($AccountType) { ([AccountType]::Domain) { ([Credential]$this).Set((get-aduser -Identity $AccountID).SamAccountName) break } ([AccountType]::Vault) { ([Credential]$this).Set([string]::Empty) break } Default { ([Credential]$this).Set([string]::Empty) break } } } [void] Set([string]$AccountID, [string]$AccountName, [pscredential]$Credential, [AccountType]$AccountType) { $this._ID = $AccountID $this._AccountName = $AccountName $this._AccountType = $AccountType switch ($AccountType) { ([AccountType]::Domain) { ([Credential]$this).Set($Credential) break } ([AccountType]::Vault) { ([Credential]$this).Set($Credential) break } Default { ([Credential]$this).Set([string]::Empty) break } } } [void] Clear() { $this._ID = 0 $this._AccountName = [string]::Empty $this._AccountType = [AccountType]::Generic ([Credential]$this).Clear() } #endregion Class Methods } class VaultAccount : Account { <# # VaultAccount Class: implements Account # Constructor uses base constructor. # Methods overrides are declared. #> hidden [int]$_VaultID hidden [string]$_AccountName hidden [bool]$_CheckedOut hidden [string]$_CheckedOutEmail hidden [int]$_MinutesLeft hidden [datetime]$_CheckOutExpireTime [bool]$CheckedOut [string]$CheckedOutEmail [int]$MinutesLeft [datetime]$CheckOutExpireTime #region Class Constructors hidden [void] Init() { Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'CheckedOut' -Value { return $this._CheckedOut } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'CheckedOutEmail' -Value { return $this._CheckedOutEmail } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'CheckOutExpireTime' -Value { return $this._CheckOutExpireTime } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'MinutesLeft' -Value { return NEW-TIMESPAN -Start (GET-DATE) -End ($this._CheckOutExpireTime) } ([Account]$this).Init() } VaultAccount () { $this.Init() $this.Clear() } #endregion Class Constructor #region Class Methods [void] Set() { $this._CheckedOutEmail = (Read-Host -Prompt 'Input email of account that checked this entry out') $this._CheckedOut = (Read-Host -Prompt 'Input $true if checked out or $false') $this._CheckOutExpireTime = (GET-DATE).AddMinutes((Read-Host -Prompt 'Input minutes left')) ([Account]$this).Set() } [void] Set([int]$ID, [string]$AccountName, [string]$CheckedOutEmail, [bool]$CheckedOut, [int]$MinutesLeft) { $this._VaultID = $ID $this._AccountName = $AccountName $this._CheckedOut = $CheckedOut $this._CheckedOutEmail = $CheckedOutEmail $this._CheckOutExpireTime = (GET-DATE).AddMinutes($MinutesLeft) ([Account]$this).Set($this._VaultID, $this._AccountName, [pscredential]::Empty, [AccountType]::Vault) } [void] Set([int]$ID, [string]$AccountName, [string]$CheckedOutEmail, [bool]$CheckedOut, [int]$MinutesLeft, [pscredential]$Credential) { $this._VaultID = $ID $this._AccountName = $AccountName $this._CheckedOut = $CheckedOut $this._CheckedOutEmail = $CheckedOutEmail $this._CheckOutExpireTime = (GET-DATE).AddMinutes($MinutesLeft) ([Account]$this).Set($this._VaultID, $this._AccountName, $Credential, [AccountType]::Vault) } [void] Clear() { $this._VaultID = 0 $this._AccountName = [string]::Empty $this._CheckedOut = $false $this._CheckedOutEmail = [string]::Empty $this._CheckOutExpireTime = [datetime]::FromFileTime(0) ([Account]$this).Clear() } # ToString Method [String] ToString() { return $this._SamAccountName } #endregion Class Methods } class DomainAccount : Account { <# Class Comments # Active Directory Class: implements Account # Constructor uses base constructor. # Methods overrides are declared. #> #region Property Declarations hidden [bool]$_Enabled hidden [bool]$_LockedOut hidden [string[]]$_MemberOf hidden [string]$_Description hidden [string]$_mail hidden [string]$_SamAccountName hidden [string]$_EmployeeID hidden [long]$_PasswordExpiryTime [bool]$Enabled [bool]$LockedOut [string[]]$MemberOf [string]$Description [string]$mail [string]$SamAccountName [int]$EmployeeID [datetime]$PasswordExpiryTime #endregion Property Declarations #region Class Constructors hidden [void] Init() { Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'Enabled' -Value { return $this._Enabled } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'LockedOut' -Value { return $this._LockedOut } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'MemberOf' -Value { return $this._MemberOf } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'Description' -Value { return $this._Description } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'mail' -Value { return $this._mail } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'SamAccountName' -Value { return $this._SamAccountName } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'EmployeeID' -Value { return $this._EmployeeID } Add-Member -InputObject $this -MemberType ScriptProperty -Force -Name 'PasswordExpiryTime' -Value { return [datetime]::FromFileTime($this._PasswordExpiryTime) } ([Account]$this).Init() } DomainAccount () { $this.Init() $this.Clear() } DomainAccount ([string]$Username) { $this.Init() $this.Set($Username) } DomainAccount ([pscredential]$Credential) { $this.Init() $this.Set($Credential) } #endregion Class Constructor #region Class Methods [void] Set() { $this.Set((Read-Host -Prompt 'Input username of AD Account')) } [void] Set([string]$Username) { #since we are effectively wiping this user entry blank, call base method as well $this.Clear() $User = $this.GetUserObject($Username) $this._Enabled = $User.Enabled $this._LockedOut = $User.LockedOut $this._MemberOf = $User.MemberOf $this._Description = $User.Description $this._mail = $User.mail $this._SamAccountName = $User.SamAccountName $this._EmployeeID = $User.EmployeeID $this._PasswordExpiryTime = $($User.'msDS-UserPasswordExpiryTimeComputed') #This is frustrating. The account should be a sid but doubles the shortname of what is stored in the objects properties #basically im trying to refactor how this should document the "Account Generic" portion of this object ([Account]$this).Set($User.SID, $User.name, [AccountType]::Domain) #([Credential]$this).Set($User.SamAccountName) } [void] Set([pscredential]$Credential) { #since we are effectively wiping this user entry blank for accounttype domain, call base method as well $this.Clear() $User = $this.GetUserObject($Credential.Username) $this._Enabled = $User.Enabled $this._LockedOut = $User.LockedOut $this._MemberOf = $User.MemberOf $this._Description = $User.Description $this._mail = $User.mail $this._SamAccountName = $User.SamAccountName $this._EmployeeID = $User.EmployeeID $this._PasswordExpiryTime = $($User.'msDS-UserPasswordExpiryTimeComputed') #This is frustrating. The account ID may be more complicated than other accounttypes #I'll research and reapproach ([Account]$this).Set($User.SID, $User.name, $Credential, [AccountType]::Domain) #([Credential]$this).Set($User.SamAccountName) } hidden [object] GetUserObject([string]$Username) { #Create an empty scaffold so that no matter whether a valid #or empty username is given the method gracefully handles this $User = { Enabled = $false LockedOut = $false MemberOf = @() Description = [string]::Empty mail = [string]::Empty SamAccountName = [string]::Empty EmpoyeeID = 0 msDS-UserPasswordExpiryTimeComputed = 0 SID = 0 Name = [string]::Empty } # if ([pscredential]::Empty -ne $Credential) { if ([string]::IsNullOrEmpty($Username) -eq $false) { $User = Get-ADUser $UserName -Properties 'msDS-UserPasswordExpiryTimeComputed', MemberOf, mail, Description, EmployeeID } return $User } [void] Clear() { $this._Enabled = $false $this._LockedOut = $false $this._MemberOf = [string]::Empty $this._Description = [string]::Empty $this._mail = [string]::Empty $this._SamAccountName = [string]::Empty $this._EmployeeID = 0 $this._PasswordExpiryTime = 0 ([Account]$this).Clear() } # ToString Method [String] ToString() { return $this._SamAccountName } #endregion Class Methods } #region Factory Classes class AccountFactory { <# # Factory Class: AccountFactory # Instance Methods generate new Accounts. # Static Properties/Methods demonstrate Storage/Fetch Concepts. #> #Store and Fetch static [Account[]] $Accounts static [Object] getByType([Object] $O) { return [AccountFactory]::Accounts.Where({$_ -is $O}) } static [Object] getByName([String] $Name) { return [AccountFactory]::Accounts.Where({$_.Name -eq $Name}) } #Create an instance [Account] makeAccount([String] $Name, [String] $Caffeine, [String] $Type) { return (New-Object -TypeName "$Type" -ArgumentList $Name, $Caffeine) } } class License { #this is an attempt to combine Credential with Account #region Property Declarations #endregion Property Declarations #region Class Constructors hidden Init([pscredential]$Credential, [Account]$Account) { $this.Init($Credential, [AccountType]::Empty) } [Diagnostics.CodeAnalysis.SuppressMessage("PSAvoidUsingPlainTextForPassword",'')] hidden Init([Credential]$Credential, [Account]$Account) { $this._Credential = $Credential $this._AccountType = $Credential.AccountType $this | Add-Member -Name "Domain" -MemberType ScriptProperty -Value { return $("LDAP://" + ([ADSI]"").distinguishedName) } -Force $this | Add-Member -Name "Username" -MemberType ScriptProperty -Value { return [string]$this._Credential.UserName } -Force $this | Add-Member -Name "Password" -MemberType ScriptProperty -Value { return [securestring]$this._Credential.Password } -Force $this | Add-Member -Name "AccountType" -MemberType ScriptProperty -Value { return $this._AccountType } -Force $this | Add-Member -Name "IsValid" -MemberType ScriptProperty -Value { if ([pscredential]::Empty -eq $this._Credential) { return $false} return $null -ne (New-Object System.DirectoryServices.DirectoryEntry($this.Domain,$this._Credential.UserName,$this._Credential.GetNetworkCredential().Password)) } -Force } License() { $this.Init([pscredential]::Empty, [AccountType]::Empty) } License([pscredential]$Credential) { $this.Init((if ($null -eq $Credential) { [pscredential]::Empty } else { $Credential }), [AccountType]::Generic ) } License([pscredential]$Credential, [AccountType]$AccountType) { $this.Init( (if ($null -eq $Credential) { [pscredential]::Empty } else { $Credential }), (if ($null -eq $AccountType) { [AccountType]::Empty } else { $AccountType }) ) } #endregion Class Constructors #region Class Methods #endregion Class Methods } #endregion Factory Classes |