Scem.Support.psm1


<#
.Synopsis
   Ensures Procdump is in the appdata\local folder
.DESCRIPTION
   This cmdlet will download procdump and persist it in the appdata\local\Microsoft\Sysinternals folder.
.OUTPUTS
   Location of the procmon executable
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   Assists in capturing memory dumps.
#>

function Get-ProcdumpLocation 
{
    [OutputType([System.IO.FileInfo])]

    $localSysinternalsAppData = Join-Path $env:LOCALAPPDATA "Microsoft\Sysinternals"

    $procdumpLocal = Join-Path $localSysinternalsAppData Procdump.exe

    if((-not (Test-Path $procdumpLocal))){
        if(-not (Test-Path $localSysinternalsAppData)){
            New-Item -ItemType Directory -Path $localSysinternalsAppData | Out-Null
        }
        
        $procdumpLocalZip = Join-Path $localSysinternalsAppData Procdump.zip
        $procdumpLiveUrl = 'https://download.sysinternals.com/files/Procdump.zip'
        Invoke-WebRequest -Uri $procdumpLiveUrl -OutFile $procdumpLocalZip

        Expand-Archive -Path $procdumpLocalZip -DestinationPath $localSysinternalsAppData
    }

    return $procdumpLocal
}

<#
.Synopsis
   Ensures Procmon is in the appdata\local folder
.DESCRIPTION
   This cmdlet will download procmon and persist it in the appdata\local folder.
.OUTPUTS
   Location of the procmon executable
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   The functionality that best describes this cmdlet
#>

function Get-ProcmonLocation 
{
    [OutputType([System.IO.FileInfo])]

    $localAppData = $env:LOCALAPPDATA

    $procmonLocal = Join-Path $env:LOCALAPPDATA Procmon.exe

    if(-not (Test-Path $procmonLocal)){
        $procmonLiveUrl = 'https://live.sysinternals.com/Procmon.exe'
        Invoke-WebRequest -Uri $procmonLiveUrl -OutFile $procmonLocal
    }

    return $procmonLocal
}

<#
.Synopsis
   Short description
.DESCRIPTION
   Long description
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
.INPUTS
   Inputs to this cmdlet (if any)
.OUTPUTS
   Output from this cmdlet (if any)
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   The functionality that best describes this cmdlet
#>

function Invoke-Procmon
{
    [CmdletBinding(DefaultParameterSetName='Parameter Set 1', 
                  SupportsShouldProcess=$true, 
                  PositionalBinding=$false,
                  HelpUri = 'http://www.microsoft.com/',
                  ConfirmImpact='Medium')]
    #[Alias()]
    [OutputType([System.IO.FileInfo])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true, 
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true, 
                   ValueFromRemainingArguments=$false, 
                   Position=0,
                   ParameterSetName='Parameter Set 1')]
        [ValidateNotNull()]
        $LogName,

        # Param2 help description
        [Parameter(ParameterSetName='Parameter Set 1')]
        [System.IO.FileInfo]
        $ConfigFile
    )


    Begin
    {
        Write-Information -MessageData "=== Invoke-Procmon Begin ==="
        $runtimeInSeconds = 10
        $currentLocation = Get-Location
        $procmonLocal = Get-ProcmonLocation
    }
    Process
    {
        if ($pscmdlet.ShouldProcess("Target", "Operation"))
        {
        }

        
        $date = Get-date
        $procmonBackingFile = Join-Path $currentLocation "$($LogName)_$($date.ToString("yyMMdd_HHmmss")).pml"
        $captureArgs = @("/AcceptEula", 
                        "/Quiet",
                        "/BackingFile $procmonBackingFile"
                        "/LoadConfig $ConfigFile"
                        "/Runtime $runtimeInSeconds")

                        
        Start-Process -FilePath $procmonLocal -ArgumentList $captureArgs -Wait 

        return Get-Item -Path $procmonBackingFile
    }
    End
    {
        Write- -MessageData "=== Invoke-Procmon End ==="
    }
}

<#
.Synopsis
   Short description
.DESCRIPTION
   Long description
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
.INPUTS
   Inputs to this cmdlet (if any)
.OUTPUTS
   Output from this cmdlet (if any)
.NOTES
   General notes
.COMPONENT
   The component this cmdlet belongs to
.ROLE
   The role this cmdlet belongs to
.FUNCTIONALITY
   The functionality that best describes this cmdlet
#>

function Invoke-ProcmonFilter
{
    [CmdletBinding(DefaultParameterSetName='Parameter Set 1', 
                  SupportsShouldProcess=$true, 
                  PositionalBinding=$false,
                  HelpUri = 'http://www.microsoft.com/',
                  ConfirmImpact='Medium')]
    [OutputType([System.IO.FileInfo])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true, 
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true, 
                   ValueFromRemainingArguments=$false, 
                   Position=0,
                   ParameterSetName='Parameter Set 1')]
        [ValidateNotNull()]
        [System.IO.FileInfo]
        $ProcmonLog
    )
    Begin
    {
        Write-Information -MessageData "=== Invoke-ProcmonFilter Begin ==="
        $procmonLocal = Get-ProcmonLocation
    }
    Process
    {
        if ($pscmdlet.ShouldProcess("Target", "Operation"))
        {
        }

        $filteredLog = $ProcmonLog.FullName.Replace(".pml", "-filtered.pml")

        $filterArgs = @("/AcceptEula", 
                        "/Quiet",
                        "/SaveApplyFilter",
                        "/Openlog $ProcmonLog",
                        "/SaveAs $filteredLog")
                        
        Start-Process -FilePath $procmonLocal -ArgumentList $filterArgs -Wait #-WindowStyle Hidden

        return Get-Item -Path $filteredLog
    }
    End
    {
        Write-Information -MessageData "=== Invoke-ProcmonFilter End ==="
    }
}


<#
.Synopsis
   Short description
.DESCRIPTION
   Long description
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
#>

function Export-SCVMMInfo {
    [CmdletBinding()]
    Param(
        [parameter(Mandatory = $false)]
        [string] $ComputerName = $env:COMPUTERNAME
        ) 
    Begin {
        if($null -eq (Get-Module virtualmachinemanager)){
            try{
                Import-Module virtualmachinemanager -ErrorAction Stop
            }
            catch [FileNotFoundException]{
                Write-Error "This does not appear to be a System Center Virtual Machine Manager."
            }
        }
        
        [Microsoft.SystemCenter.VirtualMachineManager.Remoting.ServerConnection]$vmmServer = $null
        $vmmServer = virtualmachinemanager\Get-SCVMMServer -ComputerName $env:COMPUTERNAME
    }
    Process {
        $vmmServer | ConvertTo-Json | Out-File vmmServer.json

        $hostGroups = Get-SCVMHostGroup -VMMServer $vmmServer
        $hostGroups | ConvertTo-Json | Out-File vmmHostGroups.json

        $hosts = Get-SCVMHost -VMMServer $vmmServer
        $hosts | ConvertTo-Json | Out-File vmmHosts.json
    }
    End {
        if ($null -ne $vmmServer) {
            if ($vmmServer.IsConnected) {
                $vmmServer.Disconnect()
            }
            $vmmServer = $null
        }
    }
}

<#
.Synopsis
   Exports SCOM Management Server info
.DESCRIPTION
   Exports SCOM Management Server info to a json file.
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
#>

function Export-SCOMManagementServerInfo
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidateNotNull()]
        [Microsoft.EnterpriseManagement.Administration.ManagementServer[]]
        $ManagementServer
    )

    Begin
    {
    }
    Process
    {
        # This is a hack because ConvertTo-Json does not like converting ManagmentServers.
        # When you pipe to this cmdlet, you get this error:
        # "ConvertTo-Json : An item with the same key has already been added."
        $json = $ManagementServer | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json
    }
    End
    {
        $json | Out-File ManagementServers.json
    }
}