mirror of
https://gitlab.com/JKANetwork/powerfulcomputermanager.git
synced 2026-02-18 03:01:31 +01:00
344 lines
15 KiB
PowerShell
344 lines
15 KiB
PowerShell
# Build 21. Using API 2
|
|
param([Int32]$startup=0)
|
|
|
|
$host.UI.RawUI.WindowTitle = "Powerful Computer Manager - Do Not Close"
|
|
Write-Host "Starting Powerful Computer Manager..."
|
|
|
|
$srcdir = $PSCommandPath | Split-Path -Parent
|
|
$server = (Get-Content "$srcdir\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).server
|
|
$resources = (Get-Content "$srcdir\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).resources
|
|
$64bit = [Environment]::Is64BitOperatingSystem
|
|
|
|
$computerName = [System.Net.Dns]::GetHostName()
|
|
$UUID=(Get-CimInstance Win32_ComputerSystemProduct).UUID
|
|
|
|
# Powershell of Windows / Powershell Core
|
|
if ((Get-Host | Select-Object Version).Version.Major -lt 6){#Powershell Windows (Not Core) Powershell < 6
|
|
add-type -TypeDefinition @"
|
|
using System.Net;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
public class TrustAllCertsPolicy : ICertificatePolicy {
|
|
public bool CheckValidationResult(
|
|
ServicePoint srvPoint, X509Certificate certificate,
|
|
WebRequest request, int certificateProblem) {
|
|
return true;
|
|
}
|
|
}
|
|
"@
|
|
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
|
|
}else{ # Powershell Core
|
|
$PSDefaultParameterValues +=
|
|
@{'Invoke-RestMethod:SkipCertificateCheck' = $true}
|
|
}
|
|
|
|
# Force install nuget if not installed (If not installed, it breaks uninstalls silently)
|
|
If(-not(Get-PackageProvider NuGet -ErrorAction silentlycontinue)){
|
|
Install-PackageProvider -Name NuGet -Confirm:$False -Force
|
|
}
|
|
|
|
|
|
$exists = Invoke-RestMethod -Method Post -Uri "$server/get/computerexists?ComputerName=$computerName&UUID=$UUID"
|
|
if ($exists.Result -eq "ERROR"){
|
|
if ($exists.EXITCODE -eq '3'){
|
|
Write-Host "Computer outside database:" $computerName
|
|
}else{
|
|
Write-Host "Computer and UUID of $computerName doesn't match"
|
|
}
|
|
exit
|
|
}
|
|
|
|
$Timestamp = [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds
|
|
# Hardware Data
|
|
$SOData = Get-CimInstance Win32_OperatingSystem
|
|
$SOVersion = $SOData.Version
|
|
if ($SOVersion -match "^10.0."){ #If its Windows 10, add revision number for knowing hotfix installed
|
|
$revi = -join(".",(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion' UBR).UBR)
|
|
$SOVersion += $revi
|
|
}
|
|
|
|
# Update Computer Data
|
|
$CPUInfo = (Get-CimInstance Win32_Processor) | Select-Object Name,MaxClockSpeed,ThreadCount
|
|
$CPUName = -join($CPUInfo.ThreadCount, " x ",$CPUInfo.Name.Trim()," (",$CPUInfo.MaxClockSpeed," MHz)")
|
|
$RAMInstalled = Get-CimInstance CIM_PhysicalMemory | Measure-Object -Property capacity -Sum | ForEach-Object {[math]::round(($_.sum / 1MB),2)}
|
|
$RAMFree = [Math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory/1024,0)
|
|
$RAMUsed = $RamInstalled-$RAMFree
|
|
# Disks
|
|
$objDisks = Get-CimInstance -Class win32_LogicalDisk -Filter "DriveType = '3'"
|
|
$diskResults = @()
|
|
ForEach( $disk in $objDisks )
|
|
{
|
|
$ThisVolume = "" | Select-Object Volume,Capacity,UsedSpace,FreeSpace
|
|
$ThisVolume.Volume = $disk.DeviceID
|
|
$ThisVolume.Capacity = $([Math]::Round($disk.Size / 1GB,2))
|
|
$ThisVolume.FreeSpace = $([Math]::Round($disk.FreeSpace / 1GB,2))
|
|
$ThisVolume.UsedSpace = $([Math]::Round(($disk.Size - $disk.FreeSpace) / 1GB,2))
|
|
$DiskResults += $ThisVolume
|
|
}
|
|
$DisksData = ConvertTo-Json -Depth 4 $DiskResults
|
|
$DisksData = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($DisksData)) #I can't enter to database all without encode
|
|
$lastUser = (Get-CimInstance -ClassName Win32_ComputerSystem -Property UserName -ComputerName .).UserName
|
|
# Send it
|
|
$paramInvoke = -join("$server/upd/computer?ComputerName=$computerName&UUID=",$UUID,"&SOVersion=",$SOVersion,"&SOCaption=",$SOData.Caption,"&SOBit=",$SOData.OsArchitecture.Substring(0,2),"&LastConnection=",$Timestamp,"&RAM=",$RAMInstalled,"&RAMFree=",$RAMFree,"&CPUName=",$CPUName,"&LastUser=",$lastUser,"&HDD=",$DisksData)
|
|
Invoke-RestMethod -Method Post -Uri $paramInvoke | out-null
|
|
|
|
|
|
# Load Cooks of computer
|
|
$cooks = Invoke-RestMethod -Method Post -Uri "$server/get/cookpend?ComputerName=$computerName&UUID=$UUID"
|
|
|
|
foreach ($CookName in $cooks){
|
|
Set-Location $env:temp # For downloading/copying items, use system temp location
|
|
$CookName = $CookName.CookName
|
|
$cook = Invoke-RestMethod -Method Post -Uri "$server/load/cook?CookName=$CookName&ComputerName=$computerName&UUID=$UUID"
|
|
Write-Host "Receta:" $cook.name
|
|
$CookRevision = $cook.revision
|
|
$atstartup = $cook.atstartup
|
|
if ($atstartup -eq 1 -and $startup -ne 1){ # If script has to tun at startup of computer, and there is not this moment..
|
|
Write-Host "Se salta ya que no esta arrancando/apagandose el equipo..."
|
|
continue # Go for next
|
|
}
|
|
if ($cook.only64bit -eq 1 -and $64bit -eq $False) { # If script is only for 64 bit and system is 32 bit..
|
|
Write-Host "Se salta ya que es esta receta es solo para 64 bits..."
|
|
continue # Go for next
|
|
}
|
|
if ($cook.only32bit -eq 1 -and $64bit -eq $True) { # If script is only for 32 bit and system is 64 bit..
|
|
Write-Host "Se salta ya que es esta receta es solo para 32 bits..."
|
|
continue # Go for next
|
|
}
|
|
$err = 0
|
|
$exit = 0
|
|
$inif = $False
|
|
$if = $True
|
|
$filesCopied = New-Object System.Collections.ArrayList # For REPOTOLOCAL, has a list of files copied to delete when finish (Do not store forever in temp)
|
|
foreach ($step in $cook.steps){
|
|
if ($err -eq 1 -and $noerror -eq 1){$err = 0; $errvar = ""} #If "noerror" is active, do not count errors
|
|
if ($err -eq 1 -or $exit -eq 1){break} # Halt if err ocurred (And noerror directive is not active)
|
|
$step = $step.Split("|")
|
|
$param = $step[1]
|
|
$param2 = $step[2]
|
|
Write-Host $step[0] "-" $step[1]
|
|
if($inif -eq $True -and $if -eq $False){ # Only can see "ENDIF" if is in IF and is not true
|
|
if ($step[0] -ne "ENDIF" -and $step[0] -ne "ELSE"){
|
|
Write-Host $step[0] "Not executed, IF not meet"
|
|
$step[0] = "" #Disable command
|
|
$step[1] = ""
|
|
}
|
|
}
|
|
|
|
switch ($step[0].ToUpper()) { #Command
|
|
"UNINSTALL" { # Remove program
|
|
# YOU HAVE TO CHECK IF NUGET IS INSTALLED, IF NOT, EXIT AS Error (If not doing this, program will stuck)
|
|
If(-not(Get-PackageProvider NuGet -ErrorAction silentlycontinue)){
|
|
Write-Host "You don't have NuGet installed! Aborting..."
|
|
$err = 1
|
|
}else{
|
|
# Uninstall package
|
|
Get-Package -Name "$param*" -ErrorAction Continue #This will return error if program is not installed, do not see it.
|
|
if ($? -eq $True){ #If its True, is that package exists
|
|
Get-Package -Name "$param*" -ErrorVariable errvar | Uninstall-Package -ErrorVariable errvar
|
|
if ($? -eq $False){ # If fail then put 1 (When fail, powershell returns False)
|
|
$err = 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"SERV_DISABLE" { # Disable a service
|
|
Set-Service $param -StartupType Disabled -Status Stopped -ErrorVariable errvar
|
|
if ($? -eq $False){ #If its False, it was a problem
|
|
$err = 1
|
|
}
|
|
}
|
|
"SERV_ENABLE" { # Enable a service
|
|
Set-Service $param -StartupType Automatic -Status Running -ErrorVariable errvar
|
|
if ($? -eq $False){ #If its False, it was a problem
|
|
$err = 1
|
|
}
|
|
}
|
|
{$_ -in "KILL_PROCESS","KILLPROCESS"} {
|
|
$p = Get-Process -Name "$param"
|
|
if ($? -eq $True){ # Only do something if exists
|
|
Stop-Process -InputObject $p -Force -ErrorVariable errvar -ErrorAction Continue
|
|
#if ($p.HasExited -eq $false){
|
|
# $err = 1
|
|
#}
|
|
}
|
|
}
|
|
"CD" { #CHANGE DIR, ITS DANGEROUS. IF PARAM IS EMPTY, GO TO $env:temp
|
|
if ($param -eq ""){
|
|
Set-Location "$env:temp"
|
|
}else{
|
|
Set-Location "$param"
|
|
}
|
|
if ($? -eq $false){ # Location change error
|
|
$err = 1
|
|
}
|
|
}
|
|
"CMD" { # Run a cmd command. Note: Runs at high priv.
|
|
cmd.exe /c "$param"
|
|
if ($LASTEXITCODE -ne 0){ # Error in CMD
|
|
$err = 1
|
|
}
|
|
}
|
|
"PWCMD" { # Run a powershell command. Note: Runs as high priv.
|
|
Invoke-Expression $param
|
|
if ($? -eq $false){ # Error in CMD
|
|
$err = 1
|
|
}
|
|
}
|
|
"PWSCRIPT" { # Run a powershell script. Note: Runs as high priv.
|
|
Invoke-Expression -Command $param
|
|
if ($? -eq $false){ # Error in Script
|
|
$err = 1
|
|
}
|
|
}
|
|
"REPOTOLOCAL" { # Copy file from repo location to local ($env:temp) for use in cmd or other things
|
|
Copy-Item "$resources\$param" $env:temp -ErrorVariable errvar -Recurse -Force
|
|
if ($? -eq $false){ # Error in Copy
|
|
$err = 1
|
|
}
|
|
$filesCopied.Add($param) > $null #Add to list
|
|
}
|
|
"COPY" { # Copy file from repo location to some folder
|
|
$parts = $param.Split(";")
|
|
if ($parts[1] -ne ""){ #Exists orig and dest
|
|
$orig=$parts[0]
|
|
$dest=$parts[1]
|
|
Copy-Item "$orig" "$dest" -ErrorVariable errvar -Recurse -Force
|
|
if ($? -eq $False){ # Error in Copy
|
|
$err = 1
|
|
}
|
|
}else{ #Doesn't sent right
|
|
$err = 1
|
|
$errvar = "Param not set right. Exiting..."
|
|
}
|
|
}
|
|
"REMOVE" { # Remove files / folders
|
|
Remove-Item "$param" -Recurse -Force -ErrorAction Continue # They not see errors (Because error will be file not found)
|
|
}
|
|
{$_ -in "INSTALLMSI","MSIINSTALL"} { # Installs a .msi file (From $env:temp)
|
|
Start-Process msiexec.exe -Wait -ArgumentList "/norestart /quiet /I $param" -ErrorVariable errvar
|
|
if ($? -eq $false){ # Error in MSI
|
|
$err = 1
|
|
}
|
|
}
|
|
"REGFILE" { # Imports a .reg file
|
|
reg import .\$param
|
|
if ($? -eq $false){ # Error importing reg file
|
|
$err = 1
|
|
}
|
|
}
|
|
"MSG" { # Display a message
|
|
msg * "$param"
|
|
}
|
|
{$_ -in "SLEEP","PAUSE"}{ # Pause exec some seconds
|
|
[int]$secs = $param
|
|
Start-Sleep -Seconds $secs
|
|
}
|
|
"NOERROR" { #All within NOERROR doesn't generate errors and stop scripts
|
|
$noerror = 1
|
|
}
|
|
"ENDNOERROR" {
|
|
$noerror = 0
|
|
}
|
|
"IFCOMPUTERNAME" { # If Computer Name is something
|
|
$inif = $true #This controls IF start/stop
|
|
$cname = (Get-ComputerName).CSName
|
|
if ($cname -eq "$param"){
|
|
$if = $True
|
|
}else{
|
|
$if = $False
|
|
}
|
|
# True -> Exists ; False -> Not exists
|
|
}
|
|
"IFSOFTWAREINST" { # If with software
|
|
$inif = $True #This controls IF start/stop
|
|
Get-Package -Name "$param*" -ErrorAction SilentlyContinue #This will return error if program is not installed, do not see it.
|
|
$if=$? # True -> Exists ; False -> Not exists
|
|
}
|
|
"IFSOFTWAREVER" { # If with software
|
|
$inif = $True #This controls IF start/stop
|
|
$parts = $param.Split(";")
|
|
if ($parts[1] -ne ""){ #Exists uri and filename
|
|
$p_name = $parts[0]
|
|
$p_ver = $parts[1]
|
|
Get-Package -Name "$p_name*" -MinimumVersion "$p_ver" -MaximumVersion "$p_ver" -ErrorAction SilentlyContinue #This will return error if program is not installed, do not see it.
|
|
$if=$? # True -> Exists ; False -> Not exists
|
|
}else{ #Doesn't sent right
|
|
$err = 1
|
|
$errvar = "Param not set right. Exiting..."
|
|
}
|
|
}
|
|
"IFPATHEXISTS" { # If only if a path exists (File, Folder, Registry Key..)
|
|
$inif = $True #This controls IF start/stop
|
|
Test-Path $param -PathType Any -ErrorAction SilentlyContinue
|
|
$if=$?
|
|
}
|
|
"IFPWCMD" { # If with powershell command
|
|
$inif = $True #This controls IF start/stop
|
|
Invoke-Expression $param #Executes powershell command
|
|
$if=$? # True -> Exists ; False -> Not exists
|
|
}
|
|
"IF64BIT" { # If 64 bit computer
|
|
$inif = $True
|
|
$if = $64bit # Its true if 64 bit computer
|
|
}
|
|
"IF32BIT" { # If 32 bit computer
|
|
$inif = $True
|
|
$if = !$64bit # Its true if 32 bit computer, flipped boolean
|
|
}
|
|
"ELSE" { # Turn bool $if
|
|
$if = !$if
|
|
}
|
|
"ENDIF"{ # End the if
|
|
$inif = $False
|
|
$if = $True
|
|
}
|
|
"DOWNLOAD" { #Download a file. This is a bit problematic one, will use ; to separate download and filename, and its forced to use it..
|
|
$parts = $param.Split(";")
|
|
if ($parts[1] -ne ""){ #Exists uri and filename
|
|
$progressPreference = 'silentlyContinue'
|
|
Invoke-WebRequest -Uri $parts[0] -OutFile $parts[1] -UseBasicParsing -ErrorVariable errvar
|
|
$progressPreference = 'Continue'
|
|
$filesCopied.Add($parts[1]) > $null #Add to list
|
|
}else{ #Doesn't sent right
|
|
$err = 1
|
|
$errvar = "Param not set right. Exiting..."
|
|
}
|
|
}
|
|
"EXIT"{ # Exits cook completly. If some param, exit will be with "error"
|
|
if ($param){ #Exit with error message
|
|
$noerror = 0
|
|
$err = 1
|
|
$errvar = $param
|
|
$exit = 1
|
|
}else{ #Exit as sucessful
|
|
$err = 0
|
|
$errvar = ""
|
|
$exit = 1
|
|
}
|
|
}
|
|
Default { ##DEFAULT, SAY COMMAND NOT VALID
|
|
Write-Host "Command not valid."
|
|
}
|
|
}
|
|
}
|
|
# Send results
|
|
if ($errvar){ #There is an error if this has something
|
|
$errvar = $($errvar | Out-String)
|
|
$errvar = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($errvar))
|
|
$err = 1
|
|
}else{
|
|
$errvar=""
|
|
}
|
|
if ($cook.runever -eq "1"){
|
|
$err = -1 # This is for run but not for error, is by cook saw.
|
|
}
|
|
Invoke-RestMethod -Method Post -Uri "$server/set/cookstatus?ComputerName=$computerName&UUID=$UUID&CookName=$CookName&Revision=$CookRevision&Error=$err&ErrorDesc=$errvar" | out-null
|
|
|
|
#Return to $env:temp
|
|
Set-Location "$env:temp"
|
|
#Delete files copied to temp for saving space
|
|
foreach ($element in $filesCopied) {
|
|
Remove-Item "$env:temp\$element" -ErrorAction SilentlyContinue -Recurse -Force
|
|
}
|
|
|
|
} |