httools.psm1

function ConvertFrom-HTSerializedJson
{
    [cmdletbinding()]
    Param
    (
        [Parameter(Mandatory = $true,Position=1)]
        [string]$File
    )
    Begin
    {
        $File = Get-Item -LiteralPath $File
    }

    Process
    {
        Add-Type -Assembly System.Web.Extensions
        $text = [IO.File]::ReadAllText($File)
        $parser = New-Object Web.Script.Serialization.JavaScriptSerializer
        $parser.MaxJsonLength = $text.length
        $parser.DeserializeObject($text)
    }
}

function ConvertTo-HTSerializedJson
{
    [cmdletbinding()]
    Param
    (
        [Parameter(Mandatory = $true,Position=1)]
        [System.Object]$Object,
        [Parameter(Mandatory = $true,Position=2)]
        [string]$File
    )
    Process
    {
        ConvertTo-Json $Object | Out-File -LiteralPath $File -Encoding utf8
    }
}

function Invoke-HTPlatformMessage
{
    [CmdletBinding()]
    param (
        [string]$RawMessage,
        [string]$ToDirectComponent,
        [int]$Count=1
    )
    begin {
        if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
        {
        $certCallback = '
            using System;
            using System.Net;
            using System.Net.Security;
            using System.Security.Cryptography.X509Certificates;
            public class ServerCertificateValidationCallback
            {
                public static void Ignore()
                {
                    if(ServicePointManager.ServerCertificateValidationCallback ==null)
                    {
                        ServicePointManager.ServerCertificateValidationCallback +=
                            delegate
                            (
                                Object obj,
                                X509Certificate certificate,
                                X509Chain chain,
                                SslPolicyErrors errors
                            )
                            {
                                return true;
                            };
                    }
                }
            }
        '

        Add-Type $certCallback
         }
        [ServerCertificateValidationCallback]::Ignore()
    }
    process {
        $posturi = 'https://localhost:8001'

        if($ToDirectComponent -ne '')
        {
            $posturi = "https://localhost:8003/$ToDirectComponent/1"
        }

        $param = @{
            'Uri' = $posturi;
            'Method' = 'POST';
            'Headers' = @{'Content-Type'='application/json'};
            'Body' = $RawMessage
            }

            1..$Count | ForEach-Object {
                $cmd_result = Invoke-WebRequest @param
                Write-Information "Response:`n $($cmd_result.RawContent)"
            }

            Write-Information "Post URL: $posturi"  -ForegroundColor Yellow
            Write-Information "Count: $Count" -ForegroundColor Yellow
    }
}

function New-HTTempFolder
{
    [CmdletBinding()]
    param
    (
        [parameter(Position = 0)]
        [string]$FolderName
    )
    process
    {
        if ($FolderName -eq '')
        {
            return
        }
        $root_folder = Join-Path $env:TEMP 'HTToolsTemp'

        if (-not (Test-Path $root_folder))
        {
            New-Item $root_folder -ItemType Directory | Out-Null
        }

        $root_folder = Resolve-Path $root_folder

        $folder = Join-Path $root_folder $FolderName

        if (-not (Test-Path $folder))
        {
            $ret = New-Item $folder -ItemType Directory
        }
        else
        {
            $ret = Get-Item $folder
        }
        return $ret
    }
}

function Remove-HTTempFolder
{
    [CmdletBinding()]
    param
    (
        [parameter(Position = 0)]
        [string]$FolderName,
        [switch]$FlushTemp
    )
    process
    {
        $root_folder = Join-Path $env:TEMP 'HTToolsTemp'

        if (-not (Test-Path $root_folder))
        {
            Write-Error "Root Temp Folder not initialized..,"
            return
        }

        if ($FlushTemp)
        {
            Remove-Item $root_folder -Confirm:$false -Recurse

            Write-Error "All data in temp folder deleted..."
            return
        }
        if ($FolderName -eq '')
        {
            return
        }

        $FolderName = Join-Path $root_folder $FolderName
        if (-not (Test-Path $FolderName))
        {
            Write-Error "$FolderName not found... "
            return
        }
        Remove-Item $FolderName -Recurse -Confirm:$false
    }

}

function Write-HTElasticDocument
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Justification="Function is just for debugging purposes")]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$ElasticUri,

        [Parameter(Mandatory=$true)]
        [string]$Index,

        [Parameter(Mandatory=$true)]
        [string]$Type,

        [Parameter(Mandatory=$true)]
        [string]$Document,

        [Parameter(Mandatory=$true)]
        [string]$ElasticUser,

        [Parameter(Mandatory=$true)]
        [string]$ElasticUserp
    )

    process {
        $es_username = $ElasticUser
        $es_password = $ElasticUserp
        $es_uri =  "$ElasticUri/$Index/$Type"

        $es_securecred = ConvertTo-SecureString $es_password -AsPlainText -Force

        $es_creds = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList $es_username, $es_securecred

        
        $param = @{
            'Uri' = $es_uri;
            'Method' = 'POST';
            'Credential' = $es_creds;
            'Body' = $Document
            }

        $cmd_result = Invoke-WebRequest @param

        Write-Output $cmd_result.Content

    }
}

function Get-HTLicenseDays
{
    [CmdletBinding()]
    param (
        [Parameter(Position=0, Mandatory=$true)]
        [string]
        $EndDate
    )
    process {
        
        try {
            $end = [System.DateTime]::ParseExact($EndDate, 'dd/MM/yyyy', [System.Globalization.CultureInfo]::InvariantCulture)
            Write-Host "End date is = $end"
        }
        catch {
            Write-Host "Cannot Parse date $EndDate - with parser dd/mm/yyyy"
        }

        $timespan = $end - $(Get-Date)
        Write-Output $timespan.Days
    }
}

function Show-HTComponentStoreInfo
{
    [CmdletBinding()]
    param (
        
    )
    process {
        Invoke-Expression -Command 'Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore'
    }
}

function Start-HTComponentCleanup 
{
    [CmdletBinding()]
    param (
        
    )
    process {
        Invoke-Expression -Command 'Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase'
    }

}

function Convertfrom-HTJsonString 
{
    [CmdletBinding()]
    param (
        # String input of JSON
        [Parameter(Mandatory=$true)]
        [string]
        $JsonString
    )
    process {
        $hashtbl = [HTdotnet.Tools.Prototype]::DeserializeObject($JsonString)
        return [pscustomobject]$hashtbl
    }
}

function Set-FileEncodingToUTF8
{
    [CmdletBinding()]
    param (
        # String original File Path to convert
        [Parameter(Mandatory=$true)]
        [string]
        $OriginalFilePath,

        # Leave the original file with extension .orig
        [bool]
        $RemoveOriginalFile = $true,

        # Leave original files in tempFolder
        [bool]
        $FlushTemp = $true
    )
    process {
        $tempFolderName = "FileEncodingToUTF8"
        $origFilePathInfo = Resolve-Path  $OriginalFilePath -ErrorAction Stop
        $tempFolder = New-HTTempFolder -FolderName $tempFolderName
        $tempFileName = $origFilePathInfo.Path.Split('\')[-2] + "--" + $origFilePathInfo.Path.Split('\')[-1]
        Copy-Item $origFilePathInfo.Path "$(Join-Path $tempFolder.FullName $tempFileName)"

        $origFileContent = [System.IO.File]::ReadAllText($origFilePathInfo.Path)

        if($RemoveOriginalFile)
        {
            Remove-Item $origFilePathInfo.Path -Force
        }else {
            Rename-Item -LiteralPath $origFilePathInfo.Path -NewName $($origFilePathInfo.Path + ".orig")
        }

        $origFileContent | Out-File $origFilePathInfo.Path -Encoding utf8

        if($FlushTemp)
        {
            Remove-HTTempFolder -FolderName $tempFolderName
        }
    }
}

function Format-HTByteSize
{
    [CmdletBinding()]
    param (
        # Integer byte input
        [Parameter(Mandatory=$true)]
        [Int64]
        $size
    )
    process {
        If ($size -gt 1TB) {[string]::Format("{0:0.00} TB", $size / 1TB)}
        ElseIf ($size -gt 1GB) {[string]::Format("{0:0.00} GB", $size / 1GB)}
        ElseIf ($size -gt 1MB) {[string]::Format("{0:0.00} MB", $size / 1MB)}
        ElseIf ($size -gt 1KB) {[string]::Format("{0:0.00} kB", $size / 1KB)}
        ElseIf ($size -gt 0) {[string]::Format("{0:0} B", $size)}
        Else {""}
    }
}

function Get-HTProcsessFileHandles {
    [CmdletBinding()]
    param (

    )
    
    process {
        $handleExePath = Join-Path $PSScriptRoot "\3rd\handle.exe"
        $output = & $handleExePath /accepteula


        $cmd_result = ""
        foreach ($line in $output) {
            $cmd_result += "$line`n"
        }
        $sectionPattern = "(?:\n\n[-]+\n\n)(?<process_name>\S+) pid: (?<process_pid>\d+)\s+(?<user>[^\n]+)(?<section>.*?)(?=\n\n--)"
        $sectionRegex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList ($sectionPattern,[System.Text.RegularExpressions.RegexOptions]::Singleline)

        $entryPattern = "(?<handle_hex>\S+):\s+File\s+\((?<mode>\S+)\)\s+(?<file>[^\n]+)"
        $entryRegex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList ($entryPattern,[System.Text.RegularExpressions.RegexOptions]::Singleline)
    
        $sectionMatchs = $sectionRegex.Matches($cmd_result)
        $result =  @()
        foreach ($m in $sectionMatchs)
        {
            $proc = [PSCustomObject]@{
                ProcessName = $m.Groups['process_name'].Value
                ProcessId = $m.Groups['process_pid'].Value
                Username = $m.Groups['user'].Value
                FileHandles = @()
            }

            $entries = $entryRegex.Matches($m.Groups['section'].Value)

            foreach ($entry in $entries)
            {
                $proc.FileHandles += [PSCustomObject]@{
                    FilePath = $entry.Groups['file'].Value
                    Mode = $entry.Groups['mode'].Value
                    Handle = $entry.Groups['handle_hex'].Value
                }
            }

            $result += $proc
        }

        return $result

    }
    
}

function Get-HTFileHandles {
    [CmdletBinding()]
    param (
        [string]
        $FileNamePattern = ""
    )
    
    process {
        $procHandles = Get-HTProcsessFileHandles
        $FileNamePattern = $FileNamePattern.ToLowerInvariant()
        $result = @()

        foreach ($proc in $procHandles) {
            foreach ($filehandle in $proc.FileHandles) {
                $filePath = $filehandle.FilePath.ToLowerInvariant()
                if($filePath.Contains($FileNamePattern))
                {
                    $result += [PSCustomObject]@{
                        FilePath = $filehandle.FilePath
                        Username = $proc.Username
                        ProcessName = $proc.ProcessName
                        ProcessId = $proc.ProcessId
                        Mode = $filehandle.Mode
                    }

                }
            }
        }
        return $result
    }
    
}