From cbe562da9621e05b3cd355437a5ca642eb0b731c Mon Sep 17 00:00:00 2001 From: Kevin Puertas Ruiz Date: Tue, 19 Nov 2019 09:01:26 +0100 Subject: [PATCH] Changes to doc and api/app for be able to record more things --- .gitignore | 5 +-- BD/emptydatabase.db | Bin 69632 -> 77824 bytes README.MD | 2 +- api.py | 25 ++++++++----- client/ADcomputerData.ps1 | 76 -------------------------------------- client/client.ps1 | 44 ++++++++++++++++------ doc/howto_writecook.md | 71 ++++++++++++++++++++--------------- sql.py | 19 +++++++--- sysopt.py | 3 -- 9 files changed, 105 insertions(+), 140 deletions(-) delete mode 100644 client/ADcomputerData.ps1 delete mode 100644 sysopt.py diff --git a/.gitignore b/.gitignore index 72461b8..0cb6c82 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,10 @@ *.log *.out client/configpcm.ini +client/client.sh BD/database* -reports/ __pycache__/ **/__pycache__/ .vscode/ cooks/*.yaml -control/ -_site \ No newline at end of file +control/ \ No newline at end of file diff --git a/BD/emptydatabase.db b/BD/emptydatabase.db index bc4dcde145a466a7bf816993ea33eaf2d606e31f..df8146ec9b49160cc8512fedac9950814603a452 100644 GIT binary patch delta 973 zcmZozz|!!5WrDO|J_7@TFc9+tF*6X~o~UDNn9rbRV8zQ>#lX*goq^w<|1{rU-gkTl zc)s!O=F#KX&CSC7l~acOI@d+6d7Nz^xN+ihRuj%DrlsPBhKwz#C5cHnsl|mkN%1AA zxdriHZoHuZrikF=iyU&ih6YLs8eE)8o-XmuN|X0-s@5y{CFZ6oafY}?geds=197O2 zk3y)QXJDwS4p3pRe^_c!ab|uVLLKPi=jY|6CPVZinHuEii(-ItKq$hwAZtBbpaz0CoK=kB;7|#M zg-Vl?4!gL#JYx$)#M$3BAT-1^C>YKVoIHn9hHdZ!M=TYC0~mO2MXA8Jg$5{>=42Vp zI3fNYj4I$T5iCh`)?*V7H=KNsM?x1f#l#z7iU|XCvq5wiV#>y25d+%C@CBIK84R^2 zFW@p{19Eq|$^)&Gn*4x|ZSr?6UXV~*s6NOQEX9R}dO&3c%)*AcKw6F45FS-Rn_0Ly zRGIkCZx$3d!Y`)EfoVSv_vRP&5(_2OW>s;=loaRu+=9{)U;=kb%qdP4U}TmRcS%huO%D$A0gEgWP?)5^%_;;mNDyog E0K2^v6951J delta 414 zcmZp8z|ydQWrDO|4g&*&AQUqK>3tJ*jCFGu^bD+c`F}9*bILIA`}3dX`^)=|?*Pv? z-rYQUJiEDBxW95%ab4t^$0@_HV6&hA9|u23F&N#_*Jo^0p4`YLDr{0*n3EJ=lA2o( zUy_)VlNxU#FnKkb9HYr(KTZh|pzd3nYb!O0KV#Tj`g z|74e8OYn4wcTSir&7nGZ9lvzF4i{%auzy%;QE_H|UIJ%`YeWc0$S1M5B(ylSD1p<{ zFT~Z|H3*{4IkBJwMP0DJQ)UT@qR>!J7l=6up?;o$p{_9Fob&VYQj;Ot;f5-6CImV9 zq8Q*D5bBqhn+h?5OVf~V@&YacW`09nAg#u2= Computer ID +# @param UUID -> UUID of computer +# No need password, validate from ComputerID+UUID for updates.. +## class updComputer(object): def on_get(self, request, response): logit(request) - ComputerID, UUID, Password= None, None,None + ComputerID, UUID = None, None for key, value in request.params.items(): if key == "ComputerName": try: @@ -587,10 +593,6 @@ class updComputer(object): ComputerID = value if key == "UUID": UUID = value - if key == "Password" and value == retPassword(): - Password=value - if Password is None: - response.media = {'TEXT': 'Invalid password','RESULT':'ERROR'} if ComputerID is None and response.media is None: response.media = {'TEXT': 'Error, you need a ComputerName/ComputerID to update data','RESULT':'ERROR'} elif response.media is None and ComputerID is not None and UUID is not None: @@ -613,6 +615,10 @@ class updComputer(object): response.media = sql.insert("UPDATE COMPUTERS SET RAM='"+value+"' WHERE ID_C='"+ComputerID+"'") if key == "CPUName": response.media = sql.insert("UPDATE COMPUTERS SET CPUName='"+value+"' WHERE ID_C='"+ComputerID+"'") + if key == "RAMFree": + response.media = sql.insert("UPDATE COMPUTERS SET RAMFree='"+str(value)+"' WHERE ID_C='"+ComputerID+"'") + if key == "HDD": + response.media = sql.insert("UPDATE COMPUTERS SET HDD='"+str(value)+"' WHERE ID_C='"+ComputerID+"'") ## # updCookName: Rename cook name @@ -809,7 +815,6 @@ api.add_route('/get/grpcook', getGrpCook()) # See groups of a determinated cook api.add_route('/get/lastrevisioncook', getLastRevisionCook()) # Returns number of last revision of a cook api.add_route('/get/statuscook', getStatusCook()) # See status of a cook api.add_route('/load/cook', loadCook()) # Load a cook (Transfer in json way) -api.add_route('/set/cookstatus', setCookStatus()) # Update status of a cook in a computer (OLD) api.add_route('/upd/cookstatus', setCookStatus()) # Update status of a cook in a computer api.add_route('/upd/computer', updComputer()) #Update data of computer api.add_route('/upd/cookname', updCookName()) #Update file name of cook and SQL references to it. diff --git a/client/ADcomputerData.ps1 b/client/ADcomputerData.ps1 deleted file mode 100644 index 568fe61..0000000 --- a/client/ADcomputerData.ps1 +++ /dev/null @@ -1,76 +0,0 @@ -$root = $PSCommandPath | Split-Path -Parent -. $root\config.ps1 - -$table = (Invoke-RestMethod -Method Get -Uri "$server/get/computers") # Get all computers -$DNSPrefix = (get-DnsClientGlobalSetting).SuffixSearchList[0] # Get DNS Prefix, needed to search computers in some environments - - -$array = @() - -function getPrograms($computername) { - - - #Define the variable to hold the location of Currently Installed Programs - - $UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" - - #Create an instance of the Registry Object and open the HKLM base key - - $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) - - #Drill down into the Uninstall key using the OpenSubKey Method - - $regkey=$reg.OpenSubKey($UninstallKey) - - #Retrieve an array of string that contain all the subkey names - - $subkeys=$regkey.GetSubKeyNames() - - #Open each Subkey and use GetValue Method to return the required values for each - - $allprogs = @() - - foreach($key in $subkeys){ - - $thisKey=$UninstallKey+"\\"+$key - - $thisSubKey=$reg.OpenSubKey($thisKey) - - $obj = New-Object PSObject - - $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $computername - - $obj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $($thisSubKey.GetValue("DisplayName")) - - $obj | Add-Member -MemberType NoteProperty -Name "DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion")) - - $obj | Add-Member -MemberType NoteProperty -Name "InstallLocation" -Value $($thisSubKey.GetValue("InstallLocation")) - - $obj | Add-Member -MemberType NoteProperty -Name "Publisher" -Value $($thisSubKey.GetValue("Publisher")) - - - $allprogs += $obj - - } - - return $allprogs -} - - -foreach ($comp in $table){ - $name = -join($comp.Name,".",$DNSPrefix); - if (Test-Connection -ComputerName $name -Quiet){ - Write-Output $name - $array += getPrograms($name) - }else{ - Write-Output "$name Offline" - } - -} - -#$array | Where-Object { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion, Publisher | ft -auto - -$array | Where-Object { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion | export-csv "$PSScriptRoot\..\Reports\software.csv" -NoTypeInformation -Delimiter ";" -Encoding ASCII -Write-Host "Guardado en ..\Reports\software.csv" -#$content = [System.IO.File]::ReadAllText("$PSScriptRoot\Reports\software.csv").Replace("A","") -#[System.IO.File]::WriteAllText("$PSScriptRoot\Reports\software.csv", $content) \ No newline at end of file diff --git a/client/client.ps1 b/client/client.ps1 index 4431bbb..e09feea 100644 --- a/client/client.ps1 +++ b/client/client.ps1 @@ -1,13 +1,13 @@ -# Build 9 +# Build 11 param([Int32]$startup=0) -Write-Host $startup -$root = $PSCommandPath | Split-Path -Parent -$server = (Get-Content "$root\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).server -$resources = (Get-Content "$root\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).resources +#Write-Host $startup +$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-wmiobject Win32_ComputerSystemProduct).UUID +$UUID=(Get-CimInstance Win32_ComputerSystemProduct).UUID $exists = Invoke-RestMethod -Method Get -Uri "$server/get/computerexists?ComputerName=$computerName&UUID=$UUID" if ($exists.Result -eq "ERROR"){ @@ -29,15 +29,35 @@ if ($SOVersion -match "^10.0."){ #If its Windows 10, add revision number for kno } # Update Computer Data -$CPUInfo = Get-WmiObject Win32_Processor -$RAMInstalled = Get-WmiObject CIM_PhysicalMemory | Measure-Object -Property capacity -Sum | ForEach-Object {[math]::round(($_.sum / 1MB),2)} -$paramInvoke = -join("$server/upd/computer?ComputerName=$computerName&UUID=",$UUID,"&SOVersion=",$SOVersion,"&SOCaption=",$SOData.Caption,"&SOBit=",$SOData.OsArchitecture.Substring(0,2),"&LastConnection=",$Timestamp,"&RAM=",$RAMInstalled,"&CPUName=",$CPUInfo.Name) -Invoke-RestMethod -Method Get -Uri $paramInvoke | out-null -# More info +$CPUInfo = (Get-CimInstance Win32_Processor) | Select 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 Volume,Capacity,FreeSpace + $ThisVolume.Volume = $disk.DeviceID + $ThisVolume.Capacity = $([Math]::Round($disk.Size / 1GB,2)) + $ThisVolume.FreeSpace = $([Math]::Round($disk.FreeSpace / 1GB,2)) + $DiskResults += $ThisVolume + } +$DisksData = $DiskResults |ConvertTo-Json +$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 -Invoke-RestMethod -Method Get -Uri "$server/upd/computer?ComputerName=$computerName&UUID=$UUID&LastUser=$lastUser" | out-null +# 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 Get -Uri $paramInvoke | out-null + +# More info (Only if has to be) +# $paramInvoke = -join("$server/upd/computerhis?ComputerName=$computerName&UUID=",$UUID,"&RAMFree=",$RAMFree,"&RAMUsed=",$RAMUsed,"&Timestamp=",$Timestamp,"&DisksUse=",$disksUse) +# Invoke-RestMethod -Method Get -Uri $paramInvoke | out-null +# Load Cooks of computer $cooks = Invoke-RestMethod -Method Get -Uri "$server/get/cookpend?ComputerName=$computerName&UUID=$UUID" foreach ($CookName in $cooks){ diff --git a/doc/howto_writecook.md b/doc/howto_writecook.md index 2fdb0db..ab71333 100644 --- a/doc/howto_writecook.md +++ b/doc/howto_writecook.md @@ -21,37 +21,50 @@ And then, steps. First a "steps:" line, and then line by line the steps of the c Steps are ever put like "Type of step" | "Command" You can put comments in every line putting another "|" and comments at finish, like.. "CMD|WinSCP-5.13.4-Setup.exe /VERYSILENT /NORESTART|Note: Installing WinSCP" -Cook finishes executing if they had and error (Except in a NOERROR block), or if finishes right. +Cook finishes executing if they had and error (Except inside a NOERROR block), or if finishes right. + +You have examples in the example_cooks folder Note: Cooks start in directory $env:temp (%TEMP%) from SYSTEM user. -# Type of commands -- CMD and PWCMD: cmd command or Powershell command. Cmd commands can not work properly if has quotes (Because its run as cmd /c ""), if they are a Powershell equivalent, please use it. Normally cmd command uses are for install/uninstall exe programs or some like that, because powershell doesn't wait to exit a exe command -- REPOTOLOCAL: Copy a file from REPO folder configured to local in temp folder to use it. You can copy files or folders with same command. -- INSTALLMSI: Installs an MSI file silently (Params /quiet /norestart are put, do not repeat). You can add parameters (Like INSTALLMSI|superapp.msi ADDLOCAL=extension SETASDEFAULT=1) -- NOERROR and ENDNOERROR: This is for creating a block of instructions that not captures errors, then cook works ever if instruction fails - Example: - NOERROR|For deleting a file that maybe can not exist - PWCMD|Remove-Item C:\Windows\loginstall.txt - ENDNOERROR|Finish -- SERV_DISABLE and SERV_ENABLE: Enables or disables a Windows Service -- MSG|Display a message to user -- COMMENT or REM: Makes cook comments (COMMENT|This is a comment) -- KILL_PROCESS: Kill a process name if exists -- UNINSTALL: Uninstalls a program by name if its installed. It searchs it by Powershell command 'Get-Package -Name "Program*"', take care of it. You can use to see name -- REMOVE: Removes a file or folder path from local computer. It's recursive -- SLEEP and PAUSE: Pauses execution seconds specified in param -- DOWNLOAD: This downloads a file from network/internet to $env:temp/filename. Its *required* to put a filename, that goes this way: DOWNLOAD|http://www.example.org/file.zip;filename.zip. ";" is that separates URL and filename. It seems to be a limit in PowerShell Invoke-WebRequest that limits this downloads to some like 128MB -- EXIT: Terminates a cook in this instruction. If a param is specified, exit will be with error code and the param as text of error. (Ej: EXIT|Error at seeking for file) +# Commands avaiable (LINUX IS NOT SUPPORTED YET) + +| OS | COMMAND | Description | +|----- |------------- |--------------------------------------------------------------------------------------------------------- | +| W | CMD | Cmd command. Beware of quotes, because internally is run as cmd /c "" | +| W/L | PWCMD | Powershell command, runs using Invoke-Command | +| W/L | REPOTOLOCAL | Copy a file from REPO folder configured to local in temp folder. You can copy a file or a folder | +| W | INSTALLMSI | Installs an MSI file silently (Params /quiet /norestart are put, do not repeat). You can add parameters (Like INSTALLMSI|superapp.msi ADDLOCAL=extension SETASDEFAULT=1) | +| W/L | NOERROR | Creates a block of instructions that not captures errors and continues event if fails
Example:
NOERROR|Try to delete a file that maybe can not exist
PWCMD|Remove-Item C:\Windows\loginstall.txt
ENDNOERROR|Finish | +| W/L | ENDNOERROR | Finishes NOERROR Block | +| W/L | SERV_ENABLE | Enables a service | +| W/L | SERV_DISABLE | Disables a service | +| W/L | MSG | Shows a message to user | +| W/L | REM / COMMENT | Annotation for developers in cooks | +| W/L | KILL_PROCESS | Kills a process | +| W/L | UNINSTALL | Uninstalls a software by name. (It finishes using * at Windows 'Get-Package -Name "Program*"', be care) | +| W/L | REMOVE | Removes a file or folder path from local compuer. It's recursive | +| W/L | SLEEP / PAUSE | Pauses execution seconds specified in param (SLEEP|3) | +| W/L | DOWNLOAD * | Downloads a file from network to tempFolder/filename. It's required to put a filename like: DOWNLOAD|http://example.org/file.zip;filename.zip. ";" separates URL and filename | +| W/L | EXIT | Terminates cook execution. It can take a param as error text (EXIT|Error at removing file) | +| L | BASH | Bash command | + + +- *DOWNLOAD: It seems to be a limit in PowerShell Invoke-WebRequest that limits this downloads to some like 128MB + +Inside of a Cook, you can use a simple IF query: +| OS | COMMAND | Runs if when: | +|----- |----------------- |--------------------------------------------------------------------------------- | +| W/L | IFSOFTWAREINST | When program is installed. | +| W/L | IFSOFTWAREVER | When program is installed and has X version (Name;Version) | +| W/L | IFPATHEXISTS | When if file exists | +| W/L | IFPWCMD | When powershell command returns True (Beware of command executed if using Linux) | +| W/L | IF64BIT | When computer is running a 64 Bit operating system | +| W/L | IF32BIT | When computer is running a 32 Bit operating system | +| W/L | IFWINDOWS | When computer is running Windows | +| W/L | IFLINUX | When computer is running Linux | +| L | IFBASH | When bash command returns True | +| W/L | ELSE | Else of IF... | +| W/L | ENDIF | Finishes IF block | -## If types -Inside a cook, you can use IF/ELSE/ENDIF scheme. -- IFSOFTWAREINST: Runs the if, if a program is installed. -- IFSOFTWAREVER: Runs the if, if a program is installed and has X version. (Run with two param: "Name;Version") -- IFPATHEXISTS: Runs if file exists -- IFPWCMD: If powershell command returns $true (Executed succesfully), if is run -- IF64BIT: If you are in a 64 Bit operating system -- IF32BIT: If you are in a 32 Bit operating system -- ELSE: Else.. -- ENDIF diff --git a/sql.py b/sql.py index 28b551f..c508fab 100644 --- a/sql.py +++ b/sql.py @@ -1,6 +1,5 @@ -# Build 2 +# Build 3 import sqlite3 -import sysopt #File of options from shutil import copyfile from os import path from datetime import datetime @@ -27,24 +26,32 @@ def dict_factory(cursor, row): def select(query): conn = sqlite3.connect('BD/database.db') conn.row_factory = dict_factory - if sysopt.debugsql==True: + if debugsql==True: logit("SQL: "+query) cur = conn.execute(query) return cur.fetchall() def insert(query): conn = sqlite3.connect('BD/database.db') - if sysopt.debugsql==True: + if debugsql==True: logit("SQL: "+query) try: c = conn.cursor() c.execute(query) conn.commit() conn.close() - if sysopt.debugsql==True: + if debugsql==True: logit("SQL Ok") return {'RESULT': 'OK'} except: - if sysopt.debugsql==True: + if debugsql==True: logit("SQL Error") return {'RESULT': 'SQLite3 Error'} + +def retOption(option): + try: + return select("SELECT Value FROM OPTIONS WHERE Option='"+option+"'")[0]['Value'] + except: + return None + +debugsql = retOption('DebugSQL') \ No newline at end of file diff --git a/sysopt.py b/sysopt.py deleted file mode 100644 index ba71be9..0000000 --- a/sysopt.py +++ /dev/null @@ -1,3 +0,0 @@ - -addComputers = False # False/True accept auto add computers that start client program and connect to server -debugsql = False # True is show in log all SQL queries