NN.MrfkCommands.psm1

#Region './Private/Register-Autofill.ps1' 0
$Splat = @{
    "CommandName" = "New-MrfkShippingLabel"
    "ParameterName" = "location"
    "ScriptBlock" = {
        param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

        $AllLocationNames = (Get-SnipeLocations).name | Sort-Object
        $AllLocationNames.Where({
            $_ -like "$wordToComplete*"
        }).ForEach({
            "`"$_`""
        })
    }
}
Register-ArgumentCompleter @Splat
#EndRegion './Private/Register-Autofill.ps1' 16
#Region './Public/Get-MrfkAdmCreds.ps1' 0
function Get-MrfkAdmCreds {
    param (
        [string]$admCredsPath = "$env:USERPROFILE\.creds\MRFK\adm_creds.xml"
    )

    if (!(Test-Path $admCredsPath)) {
        New-MrfkAdmCreds
    }
    
    Import-Clixml $admCredsPath
}
#EndRegion './Public/Get-MrfkAdmCreds.ps1' 12
#Region './Public/Get-MrfkComputerInfo.ps1' 0
function Get-MrfkComputerInfo {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ParameterSetName="Get computer by hostname",ValueFromPipeline,Position=0)]
        [string]$Hostname,
        [Parameter(Mandatory,ParameterSetName="Get computers by username")][string]$Username,
        [string]$MECMNameSpace = "root/SMS/site_PS1",
        [string]$MECMHost = "sccm-ps.intern.mrfylke.no",
        [string]$DC = "dc01.intern.mrfylke.no"
    )

    begin {
        try {
            $null = Get-ADUser -Filter "Name -eq 0"
        }
        catch [System.Management.Automation.CommandNotFoundException] {
            Write-Error -ErrorAction Stop -Message @"
Please install RSAT before running this function. You can install RSAT by following this guide:
https://github.com/NorskNoobing/NN.MrfkCommands#prerequisites
"@

        }

        $splat = @{
            "Credential" = Get-MrfkAdmCreds
            "ComputerName" = $MECMHost
            "ErrorAction" = "Stop"
        }
        $CimSession = New-CimSession @splat
    }

    process {
        $ComputerExportArr = New-Object -TypeName System.Collections.ArrayList
        $Notes = New-Object -TypeName System.Collections.ArrayList

        switch ($PsCmdlet.ParameterSetName) {
            "Get computer by hostname" {
                [array]$HostnameArr = $Hostname
            }
            "Get computers by username" {
                $splat = @{
                    "Query" = "Select * from SMS_R_System where LastLogonUserName = `"$Username`""
                    "Namespace" = $MECMNameSpace
                    "CimSession" = $CimSession
                }
                [array]$HostnameArr = (Get-CimInstance @splat).Name
            }
        }

        $HostnameArr.ForEach({
            $splat = @{
                "Query" = "Select * from SMS_R_System where name = `"$_`""
                "Namespace" = $MECMNameSpace
                "CimSession" = $CimSession
            }
            $MecmComputer = Get-CimInstance @splat
            
            if ($MecmComputer) {
                $splat = @{
                    "Query" = @"
select distinct SMS_G_System_PROCESSOR.*
from SMS_R_System
inner join SMS_G_System_PROCESSOR
on SMS_G_System_PROCESSOR.ResourceID = SMS_R_System.ResourceId
where ResourceId = $($MecmComputer.ResourceId)
"@

                    "Namespace" = $MECMNameSpace
                    "CimSession" = $CimSession
                }
                $CPUInfo = Get-CimInstance @splat
                
                $splat = @{
                    "Query" = @"
Select * from SMS_G_System_Computer_System_Product
where ResourceId = $($MecmComputer.ResourceId)
"@

                    "Namespace" = $MECMNameSpace
                    "CimSession" = $CimSession
                }
                $ModelInfo = Get-CimInstance @splat
            } else {
                $null = $Notes.Add("Couldn't find `"$Hostname`" in MECM.")
            }

            try {
                $ADComputer = Get-ADComputer $_
            
                $splat = @{
                    "Filter" = {objectclass -eq "msFVE-RecoveryInformation"}
                    "SearchBase" = $ADComputer.DistinguishedName
                    "Properties" = "msFVE-RecoveryPassword"
                    "Credential" = Get-MrfkAdmCreds
                    "Server" = $DC
                }
                $BitlockerRecoveryKeys = (Get-ADObject @splat)."msFVE-RecoveryPassword"
            }
            catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
                $null = $Notes.Add("Couldn't find `"$Hostname`" in AD.")
            }
            
            
            if ($MecmComputer.agentname) {
                $HeartbeatIndex = $MecmComputer.agentname.IndexOf("Heartbeat Discovery")
                $LastHeartbeat = $MecmComputer.agenttime[$HeartbeatIndex]
            }
            
            $null = $ComputerExportArr.Add(
                [PSCustomObject]@{
                    "Hostname" = $_
                    "LastLoggedOnUser" = $MecmComputer.LastLogonUserName
                    "MACAddresses" = $MecmComputer.MACAddresses
                    "Model" = $ModelInfo.Name
                    "CPUName" = $CPUInfo.Name
                    "SN" = $ModelInfo.IdentifyingNumber
                    "LastHeartbeat" = $LastHeartbeat
                    "BitlockerRecoveryKeys" = $BitlockerRecoveryKeys
                    "Notes" = $Notes
                }
            )
        })
        $ComputerExportArr
    }
}
#EndRegion './Public/Get-MrfkComputerInfo.ps1' 123
#Region './Public/Get-MrfkFreeHostnames.ps1' 0
function Get-MrfkFreeHostnames {
    param (
        [Parameter(Mandatory)][ValidateSet("LT","PC","TB")][string]$Prefix,
        [Parameter(Mandatory)][string]$LocationCode,
        [Parameter(Mandatory)][int]$Digits,
        [int]$Count,
        [string]$MECMNameSpace = "root/SMS/site_PS1",
        [string]$MECMHost = "sccm-ps.intern.mrfylke.no"
    )
    $CimSession = New-CimSession -Credential (Get-MrfkAdmCreds) -ComputerName $MECMHost -ErrorAction Stop
    $AllMecmComputers = Get-CimInstance -Namespace $MECMNameSpace -CimSession $CimSession -Query @"
Select * from SMS_R_System
"@

    
    $Filter = "$Prefix-$LocationCode-"

    $PCNumArr = $AllMecmComputers.where({
        ($_.Name -like "$Filter*") -and (
            $_.Name -like ($Filter + ((
                $_.Name.Replace("$Filter","","OrdinalIgnoreCase") -replace "^0+",""
            ).PadLeft($Digits,'0')))
        )
    }).Name

    if ($PCNumArr) {
        $PCNumArr = $PCNumArr.Replace("$Filter","","OrdinalIgnoreCase") -replace "^0+","" | Sort-Object
    }
    
    $FreePCNumArr = (1..("9" * $Digits)).where({$_ -notin $PCNumArr})

    if ($Count) {
        $FreePCNumArr = $FreePCNumArr | Select-Object -First $Count
    }
    
    $FreePCNumArr.ForEach({
        $Num = ([string]$_).PadLeft($Digits,'0')
        "$Filter$Num"
    })
}
#EndRegion './Public/Get-MrfkFreeHostnames.ps1' 40
#Region './Public/Get-MrfkUserInfo.ps1' 0
function Get-MrfkUserInfo {
    [CmdletBinding()]
    param (
        [Parameter(ParameterSetName="username")][string]$Username,
        [Parameter(ParameterSetName="displayname")][string]$DisplayName,
        [Parameter(ParameterSetName="mobilephone")][string]$MobilePhone,
        [switch]$IncludeComputerInfo,
        [switch]$ExpandComputerInfo
    )

    begin {
        try {
            $null = Get-ADUser -Filter "Name -eq 0"
        }
        catch [System.Management.Automation.CommandNotFoundException] {
            Write-Error -ErrorAction Stop -Message @"
Please install RSAT before running this function. You can install RSAT by following this guide:
https://github.com/NorskNoobing/NN.MrfkCommands#prerequisites
"@

        }
    }

    process {
        switch ($PsCmdlet.ParameterSetName) {
            "username" {
                $filter = "SamAccountName -like `"$Username`""
            }
            "displayname" {
                $filter = "DisplayName -like `"$DisplayName`""
            }
            "mobilephone" {
                $filter = "MobilePhone -like `"$MobilePhone`""
            }
        }

        #Get userinfo of the ADusers
        $ADUser = Get-ADUser -filter $filter -Properties MobilePhone,DisplayName | Select-Object @(
            "DisplayName","Name","SamAccountName","MobilePhone",
            "UserPrincipalName","Enabled","DistinguishedName"
        )

        #Pick an ADUser if we get multiple hits on the search query
        if ($ADUser -is [array]) {
            $splat = @{
                "Title" = "Found multiple hits on the input. Please select an user."
                "OutputMode" = "Single"
            }
            $ADUser = $ADUser | Out-GridView @splat
        }

        if (!$ADUser) {
            Write-Error -ErrorAction "Stop" -Message "Please select a user before continuing."
        }

        if ($IncludeComputerInfo) {
            $ComputerExportArr = Get-MrfkComputerInfo -Username $ADUser.SamAccountName
            if (!$ExpandComputerInfo) {
                $ADUser | Add-Member -MemberType NoteProperty -Name "Computers" -Value $ComputerExportArr
            }
        }

        #Post output
        $ADUser
        if ($ExpandComputerInfo) {
            $ComputerExportArr
        }
    }
}
#EndRegion './Public/Get-MrfkUserInfo.ps1' 69
#Region './Public/Invoke-MrfkShippingLabelPrint.ps1' 0
function Invoke-MrfkShippingLabelPrint {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][string]$Recipient,
        [Parameter(Mandatory)][string]$Location,
        [int]$copies = 1,
        [string]$PrinterNetworkPath = "\\print01\PR-SIT-STORLABEL"
    )

    process {
        #Get current default printer
        $defaultPrinter = (Get-CimInstance -Class Win32_Printer).where({ $_.Default -eq $true }).Name

        #Set printer named PR-STORLABEL-SSDSK to default printer
        if (!(Get-Printer -Name $PrinterNetworkPath -ErrorAction SilentlyContinue)) {
            (New-Object -ComObject WScript.Network).AddWindowsPrinterConnection($PrinterNetworkPath)
        }
        (New-Object -ComObject WScript.Network).SetDefaultPrinter($PrinterNetworkPath)
        
        #Create new Word document
        $WordObj = New-Object -ComObject Word.Application
        $null = $WordObj.Documents.Add()
        
        #Set page size and margins
        $WordObj.Selection.PageSetup.PageHeight = "192mm"
        $WordObj.Selection.PageSetup.PageWidth = "102mm"
        $WordObj.Selection.PageSetup.TopMargin = "12,7mm"
        $WordObj.Selection.PageSetup.BottomMargin = "12,7mm"
        $WordObj.Selection.PageSetup.LeftMargin = "12,7mm"
        $WordObj.Selection.PageSetup.RightMargin = "12,7mm"
        
        #Insert content
        $WordObj.Selection.Font.Bold = 1
        $WordObj.Selection.TypeText("Mottaker:`r`n")
        $WordObj.Selection.Font.Bold = 0
        $WordObj.Selection.TypeText($Recipient)
        $WordObj.Selection.TypeParagraph()
        $WordObj.Selection.Font.Bold = 1
        $WordObj.Selection.TypeText("Addresse:`r`n")
        $WordObj.Selection.Font.Bold = 0
        $WordObj.Selection.TypeText($Location)

        (1..$copies).ForEach({
            #Send To Default Printer
            $WordObj.PrintOut()
        })
        
        #Change default printer back to the previous value
        (New-Object -ComObject WScript.Network).SetDefaultPrinter("$defaultPrinter")
        
        #Close File without saving
        $WordObj.ActiveDocument.Close(0)
        $WordObj.quit() 
    }
}
#EndRegion './Public/Invoke-MrfkShippingLabelPrint.ps1' 56
#Region './Public/New-MrfkAdmCreds.ps1' 0
function New-MrfkAdmCreds {
    param (
        [string]$admCredsPath = "$env:USERPROFILE\.creds\MRFK\adm_creds.xml"
    )

    #Create parent folders for the file
    $admCredsDir = $admCredsPath.Substring(0, $admCredsPath.lastIndexOf('\'))
    if (!(Test-Path $admCredsDir)) {
        $null = New-Item -ItemType Directory $admCredsDir
    }
    
    #Create adm_creds file
    Get-Credential -Message "Enter your mrfk admin credentials" | Export-Clixml $admCredsPath
}
#EndRegion './Public/New-MrfkAdmCreds.ps1' 15
#Region './Public/New-MrfkShippingLabel.ps1' 0
function New-MrfkShippingLabel {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][ValidateScript({
            $_ -in (Get-SnipeLocations).name
        })][string]$location,
        [Parameter(Mandatory)][string]$displayname,
        [int]$copies,
        [string]$mobile,
        [string]$PrinterNetworkPath = "\\sr-safecom-sla1\PR-STORLABEL-SSDSK"
    )

    process {
        #Get the selected locations address
        $locationResult = Get-SnipeLocations -name $location

        $locationName = $locationResult.address
        $address = $locationResult.address2
        $postalCode = $locationResult.zip
        $city = $locationResult.city

        if (!$mobile) {
            try {
                $null = Get-ADUser -Filter "Name -eq 0"
            }
            catch [System.Management.Automation.CommandNotFoundException] {
                Write-Error -ErrorAction Stop -Message @"
Please install RSAT before running this function. You can install RSAT by following this guide:
https://github.com/NorskNoobing/NN.MrfkCommands#prerequisites
"@

            }

            #Search AD for phonenumber
            [string]$mobile = (Get-ADUser -Filter {DisplayName -like $displayname} -Properties mobile).mobile
        }

        if ($location) {
            $splat = @{
                "Recipient" = "$displayname`v$mobile"
                "Location" = "$locationName`v$address`v$postalCode $city"
                "PrinterNetworkPath" = $PrinterNetworkPath
                "copies" = $copies
            }
            Invoke-MrfkShippingLabelPrint @splat
        }
    }
}
#EndRegion './Public/New-MrfkShippingLabel.ps1' 48
#Region './Public/Remove-MrfkComputer.ps1' 0
function Remove-MrfkComputer {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ValueFromPipeline,Position=0)][string]$Hostname,
        [string]$MECMNameSpace = "root/SMS/site_PS1",
        [string]$MECMHost = "sccm-ps.intern.mrfylke.no"
    )

    begin {
        try {
            $null = Get-ADUser -Filter "Name -eq 0"
        }
        catch [System.Management.Automation.CommandNotFoundException] {
            Write-Error -ErrorAction Stop -Message @"
Please install RSAT before running this function. You can install RSAT by following this guide:
https://github.com/NorskNoobing/NN.MrfkCommands#prerequisites
"@

        }

        $splat = @{
            "Credential" = Get-MrfkAdmCreds
            "ComputerName" = $MECMHost
            "ErrorAction" = "Stop"
        }
        New-CimSession @splat
    }

    process {
        $MECMComputer = Get-CimInstance -CimSession $CimSession -Namespace $MECMNameSpace -Query @"
Select * from SMS_R_System where name = `"$Hostname`"
"@


        if ($MECMComputer) {
            Remove-CimInstance -CimInstance $MECMComputer
        } else {
            Write-Warning -Message "Couldn't find any computer in MECM with the name `"$Hostname`""
        }

        try {
            $ADComputer = Get-ADComputer $Hostname
        } catch {
            Write-Warning -Message "Couldn't find any computer in AD with the name `"$Hostname`""
        }

        if ($ADComputer) {
            (Get-ADObject -Filter * -SearchBase $ADComputer.DistinguishedName).ForEach({
                if($_.DistinguishedName -ne $ADComputer.DistinguishedName) {
                    Remove-ADObject $_.DistinguishedName -Credential (Get-MrfkAdmCreds) -Confirm:$false
                }
            })

            Remove-ADComputer -Identity $ADComputer.DistinguishedName -Credential (Get-MrfkAdmCreds) -Confirm:$false
        }
    }
}
#EndRegion './Public/Remove-MrfkComputer.ps1' 56