-
Posts
1,214 -
Joined
-
Last visited
shawn's Achievements
Enthusiast (6/14)
-
Rare
-
-
Rare
-
Rare
-
Rare
Recent Badges
-
Also applied to Invoke-RestMethod.
-
Hi, everyone! Patch Tuesday this week brought a forced change to the PowerShell Invoke-WebRequest command to address CVE-2025-54100. The fix for your PS command scripts is pretty simple, just add -UseBasicParsing to your IWR commands. This has been recommended syntax for a while anyway. Failure to include this switch will cause the script to stall and fail waiting for user input to confirm. This goes for the PS alias for IWR "curl", too.
-
I only use Ketarin on a couple of my own computers, never on client devices. I have custom scripts that consume information Ketarin publishes to my servers that do all the heavy lifting for managing my client devices. This allows me to control as much as possible myself and rely on as little outside crap as possible. My biggest complaint in this whole process are LibreOffice downloads when I cache a slow server URL and it takes hours to download an update on all my client devices that should only take a couple minutes. :/ The after-update command is your friend. Use it. With Kuppet you'll want to fix the user-agent and user-agent versions - that after-update command does exactly that. Add it to your downloads for Chrome & Firefox and it'll essentially maintain itself so you don't get blocked by sites that don't allow HeadlessChrome or older versions of the browser. An example of part of my after-update script parses the "todo" variable assigned to specific apps. Note specifically that it not only supports extraction (with and without paths), but diagnostics, uploading (through an external script), mega-get, copying it to my utility drive and more. The "real" version of this script adds aria2 and is over 250 lines. It also ensures that all my applications have the variables I care about created and assigned, even if they aren't in active use on that application yet. The uniformity makes it easier to fix later on and ensures that the POST data is consistent and manageable through the script. The most important feature in my after-update command is that it uses a C# invoke-webrequest to POST the details of the new download to one of my servers. This data is then stored in a couple tables (current versions and archive versions) in a database where it can be consumed by my client-side version checking routines and presented in a pretty display for user consumption (almost exclusively by me and my business partner). The site also provides a slug URL form so that with a generic URL request to the site with the slug you can download any of the applications via a quick redirect from the vendor's website without having to waste my bandwidth or parse the download information again. For those important downloads where it may not be easy or reliable to download the file through one of my management scripts on a client device later on, it sanitizes the filename and uploads the binary to one of my servers so it has a stable download URL that I control. I far prefer to have client downloads from their devices (they're almost always remote) using the vendor's actual website and bandwidth, but that's not always possible. My global before-updating command (batch) is: if "{version}"=="" if "{todo}"=="" echo ERROR /// {category:replace:&:^&} /// {spc} /// {appname:replace:&:^&} {version:replace:&:^&} /// {snotes:replace:&:^&} /// {schangelog:replace:&:^&} /// {swebsite:replace:&:^&}>> "Updates.txt" if "{version}"=="\{version\}" echo ERROR /// {category:replace:&:^&} /// {spc} /// {appname:replace:&:^&} {version:replace:&:^&} /// {snotes:replace:&:^&} /// {schangelog:replace:&:^&} /// {swebsite:replace:&:^&}>> "Updates.txt" if "{version}"==".0.0" exit 1 if "{version}"=="0.0" exit 1 if "{version}"=="" if "{todo}"=="" exit 1 if "{version}"=="" if "{todo}"=="\{todo\}" exit 1 This ensures that errors are quickly identified and stamped out. The "Updates.txt" file resides next to the Ketarin.exe and I just keep it open in N++ 24/7 so I can see errors immediately. My global "when app update fails" command (C#) is: #### Parse cached variable values $sname = $($App.Name); Try{ $serror = $($AppError.Message); } Catch{ $serror = ''; } Try{ $sfilename = $($App.CurrentLocation); } Catch{ $sfilename = ''; } Try{ $sversion = $app.variables.ReplaceAllInString("{version}", $sfiletime, $sfilename, $true); } Catch{ $sversion = ''; } if($sversion -eq "{version}"){$sversion = '';} echo 'sversion:'$sversion; Try{ $sslug = $app.variables.ReplaceAllInString("{spc}", $sfiletime, $sfilename, $true); } Catch{ $sslug = ''; } if($sslug -eq "{spc}"){$sslug = '';} echo 'sslug:'$sslug; Try{ $scategory = $($App.Category); } Catch{ $scategory = ''; } if($scategory -eq "{category}"){$scategory = '';} echo 'scategory:'$scategory; Try{ $swebsite = $app.variables.ReplaceAllInString("{swebsite}", $sfiletime, $sfilename, $true); } Catch{ $swebsite = ''; } if($swebsite -eq "{swebsite}"){$swebsite = '';} echo 'swebsite:'$swebsite; Try{ $schangelog = $app.variables.ReplaceAllInString("{schangelog}", $sfiletime, $sfilename, $true); } Catch{ $schangelog = ''; } if($schangelog -eq "{schangelog}"){$schangelog = '';} echo 'schangelog:'$schangelog; Try{ $sdownload = $app.variables.ReplaceAllInString("{sdownload}", $sfiletime, $sfilename, $true); } Catch{ $sdownload = ''; } if($sdownload -eq "{sdownload}"){$sdownload = '';} echo 'sdownload:'$sdownload; Try{ $splatform = $app.variables.ReplaceAllInString("{splatform}", $sfiletime, $sfilename, $true); } Catch{ $splatform = ''; } if($splatform -eq "{splatform}"){$splatform = '';} echo 'splatform:'$splatform; Try{ $sbits = $app.variables.ReplaceAllInString("{sbits}", $sfiletime, $sfilename, $true); } Catch{ $sbits = ''; } if($sbits -eq "{sbits}"){$sbits = '';} echo 'sbits:'$sbits; Try{ $snotes = $app.variables.ReplaceAllInString("{snotes}", $sfiletime, $sfilename, $true); } Catch{ $snotes = ''; } if($snotes -eq "{snotes}"){$snotes = '';} echo 'snotes:'$snotes; #### #### Append current log details Try{ ( "`nERROR:`t$($scategory)`t$($sslug)`t$($sname)`t$($sversion)`t$($snotes)`t$($schangelog)`t$($swebsite)`t$($serror)" | Out-File Updates.txt -Append -Encoding "UTF8" ) } Catch{ echo 'Can not write to Updates.txt'; echo "`nERROR:`t$($scategory)`t$($sslug)`t$($sname)`t$($sversion)`t$($snotes)`t$($schangelog)`t$($swebsite)`t$($serror)"; } #### And again, monitor that "Updates.txt" file like your life depends on it.
-
You can use any software you want, of course. 7-zip is probably the most popular, but I use aria2 and nircmd in a few of my scripts, and powershell for quite a few.
-
If you want to keep all the versions that Ketarin downloads just uncheck the box to "Always delete previously downloaded file" and make sure you put the version in the "save to" location. This will do exactly what you want, unless the publisher "forgets" to update the version number or the version parsing function you use breaks. Monitor errors closely and fix any where the version number is empty ASAP. As long as you use consistent variable names you can use the the after-update command to do anything you want with the data.
-
Check Boxes to Select Specific Packages for a Specific Software
shawn replied to JohnBoyTheGreat's topic in Feature requests
I consider all the entries in the online database as "starters." It's a good place to begin, but if you want to control how it really works or do anything more than simply download or install then you're going to end up editing it for your own use. Please check out the templates. There are some pretty extensive ones that demonstrate exactly how you could do that. Others, like my WordPress example, allow you to pull down plugins or themes from WP with just a couple details from the website. @CybTekSol wrote a great tutorial on how to use them. -
Existing downloads are difficult since the data most likely isn't there anymore (unless you stored it in a variable). However, for new downloads you just have to set the property on the Application tab for each app. I use the following in the "Save to file" option on the Application tab in almost all of mine, which stores it in a folder named based on the Category, one folder above where Ketarin is stored, replacing spaces and ampersands (&) with underscores then appending a dash and the version number: ..\{category}\{appname:regexreplace:([\s\t\r\n\-\&]+):_}-{version}.{url:ext} This results in a structure like this:
-
I need to preface my response here with a simple statement: I do not use Ketarin to do any installations. At all. I play with it only so I can help people here. It's a feature others use, but I automate the living crap out of stuff externally and use those so I am not tied to a large library that might not be possible to use remotely. This is possible already using categories: ketarin.exe /silent /category=Security You can also use the /APPNAME switch to select a specific application in case you want to install from several different categories. If you don't want to do that you could also juggle categories from the command line using db4s (the Ketarin database is SQLite), then use the /category switch to install them. I would recommend you do that with a copy of your Ketarin DB (then use the "/database=newfile.db" switch) that way you don't have to try to put them back the way they're supposed to be in your real ketarin.db file.
-
You can create any column you want in Ketarin and if you sort by that column then they'll be organized cleanly. You can make a custom column for shares (or anything else), though if you don't want to use Category for it. More about custom columns here and here. I use the Category field to manage my local downloads using the "save to file" pattern "..\{category}\{appname:regexreplace:([\s\t\r\n\-\&]+):_}-{version}.{url:ext}" for almost everything. In the Ketarin main window just sort by the Category column then click the Category group header to select everything in that Category, CTRL+C, then paste it into Notepad++. If you want a table-style view instead of the XML export use CTRL+SHIFT+C instead of CTRL+C, then paste it into Notepad++ with the Columns++ plugin installed and enabled.
-
If you're using the setup instruction option "start process" there's an option to "wait until process has exited." Use that and it will not proceed to the next step until this step is complete. If the process shells out another process then that process might not be covered, however. If this is not working for you please share what you have so we can help. As for hints, make sure you use the "{file}" variable in whatever instructions you use and it will be the exact local filename for this download regardless of the filename pattern, version number or folder you put it in. You can use functions to get even more capabilities out of that variable. Several other great tips and demonstrations in wiki.
-
Sadly, this is going to be 100% dependent on the individual application and is beyond the scope of what Ketarin itself is for. Very few download services provide the means to download an older version and those that do each have a different means to implement it. If all you're concerned with is keeping archival copies locally (and not the URLs to re-download them) then it's as simple as unchecking the box "always delete previously downloaded file" on the "Advanced settings" tab. Make sure your download destination/pattern includes the various important pieces of information you require (application name, bit-type, release type, OS, platform, and so on) to make sure they don't get overwritten. There are ways to roll your own archive using the global "After updating an application" command, but will be dependent on collecting that information yourself into a persistent database of some sort. I do this in my archival script. In the "after" command I POST to one of my domains with the data from the updated application. The remote script parses the data and inserts it into two separate tables, one that has the archival list of all updates and one that has the most recent version. Among the things I collect are the version, download URL, changelog, OS and release type. Some apps can't be updated directly with Ketarin so we have to use an exit 3 bypass to get around that while keeping the trigger functional. Afterwards you can do anything you want with the data since you control the database. One example is the XSL I posted here.
-
While the Ketarin online database is a massive and useful engine for individual apps and to build your own library from common shared sources, I do personally require my own repository which is that business logic I described in my message above. It's actually very simple to implement, though it does require on online presence. I publish all changes to all apps directly to my server so I can use them through my remote support service to check for and install updates. More about this in my response to your versions post.
-
While the online database is currently broken from within Ketarin, you can access each individual application here. You can share groups of items as XML directly from your database by selecting the members then using CTRL+C. This will copy the applications to your clipboard and you can paste it into your favorite text editor for sharing. Use a code block to share it on the forum.
-
Check Boxes to Select Specific Packages for a Specific Software
shawn replied to JohnBoyTheGreat's topic in Feature requests
Templates are ideal for this purpose. Lots of examples listed here. The biggest benefit of templates is that inevitably when a website changes how it works or even moves a period in the content that ends up messing up your application, all you have to do is fix the template itself then drag it back into Ketarin for Ketarin to update all applications based on the template. -
Here's a link to a mostly-sanitized version of my database. I had to strip out some of my business logic and a bunch of apps that have licensing, logins and other details but it should give you a good head start. I do rely heavily on Kuppet. You should, too. It's awesome and easily the best supporting software for Ketarin.
