Get-Cesi.psm1

function Get-Cesi {
    [cmdletbinding()]
    Param
    (
        [Parameter(
            ValueFromPipeline = $true,
            ParameterSetName = 'vm'
        )]
        [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VM,
        [Parameter(ParameterSetName = 'dept')]
        [String] $department,
        [Parameter()]
        [String] $csvPath = '~/git/virt/scripts/Hosting Customer Catalog - Customer Catalog.csv',
        [Parameter(ParameterSetName = 'vm')]
        [Switch] $groupByDept,
        [switch] $LiveData, # if this switch is used, the function will download the csv from the google sheet, azure is needed for keys/auth
        [switch] $UseAzIdentity # useful for running in azure non-interactively, uses the managed identity
    )
    begin {
        try {
            if (!$LiveData) {
                # check age of csv, recommend downloading again if past 30 days?
                $csv = $csvPath | Get-ChildItem -ErrorAction Stop
                if ($csv.CreationTime -lt ((Get-Date).AddMonths(-1))) {
                    Write-Warning 'The CSV file is older than 30 days. Please download a new copy.'
                    Write-Warning 'https://docs.google.com/spreadsheets/d/1Uyd0_dhfadwGINJ-KvKu5nGNq_27VRG5RUq1Jio392c/edit#gid=1297794778'
                }

                # try to import the data

                $csvData = Import-Csv -Path $csv
            }
            else {
                #connect to azure if not already connected
                if (-not (Get-AzContext)) {
                    if ($UseAzIdentity) {
                        Connect-AzAccount -Identity
                    }
                    else {
                        Connect-AzAccount
                    }
                }
                $ResourceGroupName = 'HEAT-Automation-TST'
                $AcctName = 'AutoAccount-TST'
                $KeyVault = (Get-AzAutomationVariable -ResourceGroupName $ResourceGroupName -AutomationAccountName $AcctName -Name 'Automation-KV').Value
                $base64value = Get-AzKeyVaultSecret -Name 'virt-infra-doc' -VaultName $keyVault -AsPlainText
                $certpwd = Get-AzKeyVaultSecret -Name 'virt-infra-doc-pwd' -VaultName $keyVault -AsPlainText
                $byteArray = [System.Convert]::FromBase64String($base64value)
                $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($byteArray, $certpwd, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)

                $Scope = 'https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file'
                $ISS = 'new-infradocs@vmware-infra-doc.iam.gserviceaccount.com'

                $accessToken = Get-GOAuthTokenService -scope $scope -iss $ISS -certObj $cert
                $owner = 'Customer Catalog'
                $SpreadsheetID = '1Uyd0_dhfadwGINJ-KvKu5nGNq_27VRG5RUq1Jio392c'
                $csvData = Get-GSheetData -accessToken $accessToken -cell AllData -sheetName $owner -spreadSheetID $SpreadsheetID
            }
        }
        catch {
            throw 'Unable to import Data.'
        }
        $objects = @()

    } process {
        if ($VM) {
            $department = ($vm | Get-TagAssignment -Category 'Department').Tag.Name
        }
        if ($department ) {
            #-and ($objects.DepartmentId -notcontains $department)){
            $deptInfo = $csvData | Where-Object { $_.'Unit Short ID' -eq $department }
            $deptObj = [PSCustomObject]@{
                VM              = $vm.Name
                DepartmentId    = $deptInfo.'Unit Short ID'
                DepartmentName  = $deptInfo.'Unit Long Name'
                Contacts        = $deptInfo.'Contact(s) (Customer Contacts for General Notifications & Inquiries and Outages & Issues)'
                Director        = $deptInfo.'IT Director, Unit IT Lead, or Service Owner'
                WinAdmins       = $deptInfo.'Administrators Windows'
                LinuxAdmins     = $deptInfo.'Administrators Linux'
                SMEAdmins       = $deptInfo.'Administrators Self-Managed'
                WinRequestors   = ($deptInfo.'Authorized Requestors Windows'.split(',').trim() | ForEach-Object { $_ + '@umn.edu' }) -join '; '
                LinuxRequestors = ($deptInfo.'Authorized Requestors Linux'.split(',').trim() | ForEach-Object { $_ + '@umn.edu' }) -join '; '
                SMERequestors   = ($deptInfo.'Authorized Requestors Self-Managed'.split(',').trim() | ForEach-Object { if ($_) { $_ + '@umn.edu' } }) -join '; '
                OnBoardDate     = $deptInfo.'On-boarding Date'
            }
            $objects += $deptObj

        }
        else {
            $deptObj = [PSCustomObject]@{
                VM             = $vm.Name
                DepartmentId   = 'Undefined'
                DepartmentName = 'Undefined'
            }
            $objects += $deptObj
        }

    } End {
        $count = $objects.count
        Write-Host "Found $count vms"
        if ($groupByDept) {
            #how do
            $objects = $objects | Group-Object -Property 'DepartmentId' -AsHashTable
            $groupedObjects = @()
            foreach ($item in $objects.keys) {
                $deptObj = [PSCustomObject]@{
                    VM              = $objects.item($item).vm -join ' | '
                    DepartmentId    = $objects.item($item).departmentid | Get-Unique
                    DepartmentName  = $objects.item($item).departmentName | Get-Unique
                    Contacts        = $objects.item($item).Contacts | Get-Unique
                    Director        = $objects.item($item).Director | Get-Unique
                    WinAdmins       = $objects.item($item).WinAdmins | Get-Unique
                    LinuxAdmins     = $objects.item($item).LinuxAdmins | Get-Unique
                    SMEAdmins       = $objects.item($item).SMEAdmins | Get-Unique
                    WinRequestors   = $objects.item($item).WinRequestors | Get-Unique
                    LinuxRequestors = $objects.item($item).LinuxRequestors | Get-Unique
                    SMERequestors   = $objects.item($item).SMERequestors | Get-Unique
                    OnBoardDate     = $objects.item($item).OnBoardDate | Get-Unique
                }
                $groupedobjects += $deptObj
            }
            return $groupedObjects
        }
        else {
            return $objects
        }
    }
}

function New-CesiUnit {
    <#
    .DESCRIPTION
    Creates a new tag in the 'Department' category for the given unit short ID.
    .PARAMETER UnitShortID
    The short ID for the unit.
    .PARAMETER Description
    A description of the unit.
    .EXAMPLE
    New-tag -Category 'Department' -Name 'VHL' -Description 'Visible Heart Laboratories'
    #>

    param (
        [String] $UnitShortID,
        [String] $Description
    )
    New-Tag -Category 'Department' -Name $UnitShortID -Description $Description
}


function Remove-CesiUnit{
    <#
    .DESCRIPTION
    Removes an existing tag if no vms are found
    .PARAMETER UnitShortID
    The short ID of the cesi unit
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [string]$UnitShortID
    )

    $tag = get-tag -Category 'Department' | Where-Object {$_.name -like $UnitShortID}

    if ((Get-VM -Tag $tag).count){
        Remove-Tag $tag
    } else {
        Write-Error "VMs found with $UnitShortID, will not delete the tag."
    }

}