CoreCLI.psm1

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
function Format-Json([Parameter(Mandatory, ValueFromPipeline)][String] $json) {
  $indent = 0;
  ($json -Split '\n' |
    % {
      if ($_ -match '[\}\]]') {
        # This line contains ] or }, decrement the indentation level
        $indent--
      }
      $line = (' ' * $indent * 2) + $_.TrimStart().Replace(': ', ': ')
      if ($_ -match '[\{\[]') {
        # This line contains [ or {, increment the indentation level
        $indent++
      }
      $line
  }) -Join "`n"
}

Function SelectExplorerFile {
$openFileDialog = New-Object windows.forms.openfiledialog   
$openFileDialog.initialDirectory = [System.IO.Directory]::GetCurrentDirectory()   
$openFileDialog.title = "Select PublishSettings Configuration File to Import"   
$openFileDialog.filter = "All files (*.*)| *.*"   
$openFileDialog.ShowHelp = $True   
Write-Host "Select File to upload to Core: (see FileOpen Dialog)" -ForegroundColor Green  
$result = $openFileDialog.ShowDialog()   # Display the Dialog / Wait for user response
# in ISE you may have to alt-tab or minimize ISE to see dialog box
# $result
if($result -eq "OK")    {    
        $OpenFileDialog.filename   
        $Script:SelecetedPath = $OpenFileDialog.filename
        #$OpenFileDialog.CheckFileExists
        Write-Host "File Selected!" -ForegroundColor Green 
    } 
    else { Write-Host "Import Settings File Cancelled!" -ForegroundColor Yellow
    break} 
}



Function SelectExplorerFolder ($initialDirectory)
{
    Write-Host "Select Folder to upload to Core: (see FileOpen Dialog)" -ForegroundColor Green 
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
    $foldername = New-Object System.Windows.Forms.FolderBrowserDialog
    $foldername.Description = "Select a folder"
    $foldername.rootfolder = "MyComputer"

    if($foldername.ShowDialog() -eq "OK")
    {
        $folder += $foldername.SelectedPath
        Write-Host $folder
        Write-Host "Folder Selected!" -ForegroundColor Green 
    } Else {Write-Host "Import Settings File Cancelled!" -ForegroundColor Yellow
    break}
    $script:SelecetedPath = $folder
    return $folder
}



function Set-CoreURI{
    param(
 [string]$CoreIP
 )
 if (!$CoreIP){ $CoreIP = Read-Host "Please enter IP:Port of your MetaDefender Core instace.
Example: 192.168.1.2:8008
"

 }
 try {
     $url = "http://$CoreIP"
     Invoke-RestMethod -Uri $url/stat/engines -Method Get -TimeoutSec 2 | Out-Null
    } catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
    }
    $url = "http://$CoreIP"
         New-Item -Path $env:APPDATA -Name "CoreURI.txt" -ItemType "file" -Value "$url" -Force | out-null
         write-host "Core set to $url"
         write-host ""

    }


function Scan{
    param(
        [Parameter(Mandatory=$false)][string]$Path,
        [switch]$FullDetails,
        [switch]$SelectFile,
        [switch]$SelectFolder
    )
    if ($Path) {
    if ((get-item $Path).PSIsContainer -ne $true) {ScanFile $Path}Else{ScanFolder $Path}
    }
    if ($SelectFile){
    SelectExplorerFile
    ScanFile $SelecetedPath

    }
    if ($SelectFolder){
    SelectExplorerFolder
    ScanFolder $SelecetedPath
    }
    }



function ScanFile($PathVar){

Try {
   
   
         $InputPath = $PathVar
         if (Test-path $env:APPDATA\CoreURI.txt) {
             write-host "Uploading File..."
             $site = Get-Content -Path $env:APPDATA\CoreURI.txt
             $uri = "$site/file"
             $ProgressPreference = 'SilentlyContinue'
             $response =  Invoke-RestMethod -Uri $uri -Method Post -InFile $InputPath -UseDefaultCredentials
             $response = $response -Replace "@{data_id=","" -Replace "}",""
             $resultURI = "$uri/$response"
             $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
     
             if ($resultResponse -clike '*Processing*') {
             write-host "Processing...
             "

             DO {
             Start-Sleep -s 3
             $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
    
             } while ($resultResponse -clike '*Processing*')
             }
              if($FullDetails){
        write-host $resultResponse
        } 
        Else {
        $resultResponse = $resultResponse | ConvertFrom-Json
        write-host " Data ID:" $resultResponse.data_id `n "Profile:" $resultResponse.process_info.profile `n "Result:" $resultResponse.process_info.result `n "Process time:" $resultResponse.process_info.processing_time
        if (!$resultResponse.process_info.blocked_reason){
        write-host `n
        continue
        } Else {write-host " Blocked Reason:" $resultResponse.process_info.blocked_reason}
        }
            } 
         Else {
         write-host "
         No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
         Example: Set-CoreURI 192.168.1.2:8008
         "

        }
        write-host `n
    } catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
}
}


function ScanFolder($PathVar){

Try {
         $InputPath = $PathVar
         if (Test-path $env:APPDATA\CoreURI.txt) {
             $outputFolder = Split-Path $InputPath -leaf
             Compress-Archive $InputPath -CompressionLevel Optimal -DestinationPath C:\Windows\Temp\$outputFolder.Zip
             $outputZip = "C:\Windows\Temp\$outputFolder.Zip"
             write-host "Uploading Folder..."
             $site = Get-Content -Path $env:APPDATA\CoreURI.txt
             $uri = "$site/file"
             $ProgressPreference = 'SilentlyContinue'
             $response =  Invoke-RestMethod -Uri $uri -Method Post -InFile $outputZip -UseDefaultCredentials
             $response = $response -Replace "@{data_id=","" -Replace "}",""
             $resultURI = "$uri/$response"
             $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
             if ($resultResponse -clike '*Processing*') {
             write-host "Processing...
             "

             DO {
                 Start-Sleep -s 3
                 $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
             } while ($resultResponse -clike '*Processing*')
             }
                Remove-Item $outputZip
                if($FullDetails){
        write-host $resultResponse
        } Else {
        $resultResponse = $resultResponse | ConvertFrom-Json
        write-host " Data ID:" $resultResponse.data_id `n "Profile:" $resultResponse.process_info.profile `n "Result:" $resultResponse.process_info.result `n "Process time:" $resultResponse.process_info.processing_time
        if (!$resultResponse.process_info.blocked_reason){
        write-host `n
        continue
        } Else {write-host " Blocked Reason:" $resultResponse.process_info.blocked_reason}
        }
            } 
         Else {
         write-host "
         No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
         Example: Set-CoreURI 192.168.1.2:8008
         "

        }
      write-host `n  
    } catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
}
}


function Get-CoreURI {
if (Test-path $env:APPDATA\CoreURI.txt) {
Get-Content -Path $env:APPDATA\CoreURI.txt } Else {
 write-host "
 No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
 Example: Set-CoreURI 192.168.1.2:8008
 "

}
} 


function Get-ScanResult{
   param(
 [switch]$FullDetails,
 [string]$StringCatch,
 [string]$Hash,
 [string]$DataID
 )
 Try {
        if (Test-path $env:APPDATA\CoreURI.txt) {
        $site = Get-Content -Path $env:APPDATA\CoreURI.txt
        if ($Hash){
        $uri = "$site/hash"
        $resultURI = "$uri/$Hash"
        }
        if ($DataID){
        $uri = "$site/file"
        $resultURI = "$uri/$DataID"
        }
        if (!$Hash -and !$DataID){
Write-Host "No Data ID or Hash value enterted or specified.
  Use the following format: Get-ScanResult -DataID 5513e589bcd74ec5a42ede64abbde133
                        Or: Get-ScanResult -Hash 3395856ce81f2b7382dee72602f798b642f14140
        "

        break
        }

    $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
     
    if ($resultResponse -clike '*Processing*') {
    write-host "Processing...
    "

    DO {
    Start-Sleep -s 3
    $resultResponse = Invoke-RestMethod -Uri $resultURI -Method Get -UseDefaultCredentials | ConvertTo-Json | Format-Json
    
    } while ($resultResponse -clike '*Processing*')
    }
    if($FullDetails){
        write-host $resultResponse
        } 
        Else {
        $resultResponse = $resultResponse | ConvertFrom-Json
        write-host "Data ID:" $resultResponse.data_id `n "Profile:" $resultResponse.process_info.profile `n "Result:" $resultResponse.process_info.result 
        if (!$resultResponse.process_info.blocked_reason){
        write-host `n
        continue
        } Else {write-host " Blocked Reason:" $resultResponse.process_info.blocked_reason}
        }
            } 
         Else {
         write-host "
         No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
         Example: Set-CoreURI 192.168.1.2:8008
         "

        }
        write-host `n
    } catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
}
}


function Get-ProductVersion {
try {
    if (!$password) {Set-Creds}
    if (Test-path $env:APPDATA\CoreURI.txt) {
        $uri = Get-Content -Path $env:APPDATA\CoreURI.txt
        $params = @{
         "password"="$password";
         "user"="$usrname";
            }
        $Session = Invoke-RestMethod -Uri $uri/login -Method Post -Body ($params|ConvertTo-Json) -ContentType "application/json"
        $ID = $Session.session_id
        $headers = @{
            'apikey' = "$ID"
                }
        Invoke-RestMethod -Uri $uri/version -Method Get -Headers $headers
} Else {
 write-host "
 No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
 Example: Set-CoreURI 192.168.1.2:8008
 "

}
} catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
}

}

function Get-NodeStatus{
    param(
     [switch]$FullDetails
     )
try {
    if (!$password) {Set-Creds}
    if (Test-path $env:APPDATA\CoreURI.txt) {
        $uri = Get-Content -Path $env:APPDATA\CoreURI.txt
        $params = @{
         "password"="$password";
         "user"="$usrname";
            }
        $Session = Invoke-RestMethod -Uri $uri/login -Method Post -Body ($params|ConvertTo-Json) -ContentType "application/json"
        $ID = $Session.session_id
        $headers = @{
            'apikey' = "$ID"
                }
        $response = Invoke-RestMethod -Uri $uri/stat/nodes -Method Get -Headers $headers
        $response = $response | ConvertTo-Json -depth 10
        if ($FullDetails){Write-Host $response}
        Else {
         $parse = ConvertFrom-Json -InputObject $response
         Write-Host "
 CPU Cores: "
 $parse.statuses.cpu_cores `n `
         "Max Node Count: " $parse.max_node_count `n `
         "Free Disk Space: " $parse.statuses.free_disk_space " (in bytes)" `n `
         "Operating System: " $parse.statuses.os `n `
         "System Memory: " $parse.statuses.total_mem `n `
         "Product Version: " $parse.statuses.version `n `
         "Scan Queue: " $parse.statuses.scan_queue `n   
        }
} Else {
 write-host "
 No Core URI found. Please establsh the core scanning URI by entering: Set-CoreURI IP:Port
 Example: Set-CoreURI 192.168.1.2:8008
 "

}
} catch [System.Net.WebException]{
        write-host "Server Unavailable..."
        Continue
}

}

Function Set-MaxFileSize {
param(
 [string]$FileSize
 )
if (!$FileSize) {$FileSize = Read-Host "Set File Size in MB"}
if (!$password) {Set-Creds}
if (Test-path $env:APPDATA\CoreURI.txt) {
        $uri = Get-Content -Path $env:APPDATA\CoreURI.txt
        $params = @{
         "password"="$password";
         "user"="$usrname";
            }
        Write-Host "Updating..."
        $Session = Invoke-RestMethod -Uri $uri/login -Method Post -Body ($params|ConvertTo-Json) -ContentType "application/json"
        $ID = $Session.session_id
        $uri = "$uri/admin/export"
        $headers = @{
            'apikey' = "$ID"
                }
        $response = Invoke-RestMethod -Uri $uri -Method Get -UseDefaultCredentials -Headers $headers
        $response.config.'policy.rule.rule'.items | Where{$_.name -eq 'File Process'} | ForEach{$_.option_values.'scan.filescan.max_file_size' = [int]$FileSize}

        $response = $response | ConvertTo-Json -depth 100
        #$response = $response.replace("`n","").replace("`r","").replace("$re","")
        #$response = $response -replace ' {2,}', ''
        New-Item -Path $env:APPDATA -Name "config_export.json" -ItemType "file" -Value $response | Out-Null
        $uri = Get-Content -Path $env:APPDATA\CoreURI.txt
        $uri = "$uri/admin/import"
        $JSON = Get-Content -Path $env:APPDATA\config_export.json
        Invoke-RestMethod -Uri $uri -Method Post -Body $JSON -UseDefaultCredentials -Headers $headers -ContentType "application/json"
        Remove-Item $env:APPDATA\config_export.json
                }
                }

Function Set-Creds {
$global:usrname = Read-Host "User Name"
$global:password = Read-Host -assecurestring "Password"
$global:password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
Write-Host "Credentials set for this session!"
}


function Get-CoreCLIHelp {
write-host "
The Core CLI module adds several functions to use with your MetaDefender Core instace.
New commands available include:
 
Scan <Path to file or folder> Use this command to scan indivual files or Archives.
                                          
                                             Optional paramaters:
                                               -SelectFile
                                                Use instead of Path to select file with
                                                File Explorer GUI.
                                          
                                               -SelectFolder
                                                Use instead of Path to select folder with
                                                File Explorer GUI.
                                          
                                               -FullDetails
                                                Get a full JSON response of scan.
     
Get-ScanResult <Data ID or Hash Value> Fetch details of a specific scan result.
                                             
                                            Must Specify one of the following:
                                              -DataID <DataID Value>
                                              Example: Get-ScanResult -DataID 5513e589bcd74ec5a42ede64abbde133
                        
                                              -Hash <Hash Value>
                                              Example: Get-ScanResult -Hash 3395856ce81f2b7382dee72602f798b642f14140
 
Set-CoreURI <IP:PORT> Establsh the core scanning URI by entering: Set-CoreURI IP:Port.
                                             Example: Set-CoreURI 192.168.1.2:8008
 
Get-CoreURI Get the current Core address and port set to the modual.
 
Get-ProductVersion Fetch details about the product version.
 
Get-NodeStatus Fetch system data and node status (Scan Queue).
 
"

}


Write-Host "
CoreCLI Module imported!
Disclaimer: OPSWAT or its associated partners are not responsible for the use and distribution of this module.
            The module was designed for an ease of use command line interface to interact with MetaDefender Core.
            OPSWAT is not resposible for the continued maintenance of this open-source script.
            Use at your own risk!
Enter Get-CoreCLIHelp for command options.
"