Scripts - Prerun Conditional Statements

My request would be conditional statements that run before the script (ps1 portion) runs. I’m wondering if having conditional statements that run before a script is executed would help cut down on some wasted resources on both the server and endpoint. So before the script is executed, the conditional statement runs, if it isn’t satisfied, the script doesn’t run. In some instances, this could be checking the database and the machine doesn’t have to be online. Less scripts in the queue, less scripts running on each endpoint. For example, a software install script could check and see if the software is listed in Syncro, if so, it aborts and doesn’t run the script.

1 Like

Just to name a few other statements.
If OS =
If Custom Asset Field =
If Form Factor =
If Antivirus =

such an awesome idea!!!

This would be Great, I’d add, If User is logged in for scripts that run as User.
Being able to check stuff like this would really reduce the number of script jobs we run

Can you elaborate on this one? You should be able to report back on scripts that didn’t run because a user wasn’t logged in from PS directly. This is off topic, but I am curious what specifically you are trying to do there.

I’m talking about scripts in Syncro that are set to run as the logged in user, if there is no logged in user they just fail. Which currently we have set to generate an email that I then have to triage. The only reason we run stuff as a logged in user is to tweak things in user space that are not (easily) accessible from the system account.

Really I’d want an active user session to be treated with the same logic as offline assets so a script that needs to run as a logged in user would just queue until a user logs in and then de-dupe etc. but having a graceful way to handle it built in rather than generating a failure I have to triage and then case by case try to come up with what the best remediation is would be an improvement.

Ok so you are already detecting those then it sounds like. Queueing is an interesting idea I think… but how would you handle it where some secondary user logged on instead of the one you were intending to target? I assume the script logic would fire off them regardless, right?

There’s probably something that could be done here, just not sure what would be bulletproof off the top of my head.

This is something I’ve been used to with other RMM platforms. So instead of Syncro needing to download and run a PS1 every time on the asset, it is able to run logic before it gets to that part. There’s a lot of data in Syncro that can be used before a script is needed on the machine.

Let’s say an update for Windows 10 came out and it broke it, all other operating systems are fine. So you create a script with the fix, but you don’t need it to “accidentally” run on the other operating systems. So you build into the logic to look for the operating system and exclude all but Windows 10. There’s several ways to do this in PS, sometimes things run as intended, sometimes it takes a few tries to tweak a script to do what you want it to do. PS is powerful, flexible, but has a learning curve. Instead, this is handled by Syncro, just like your saved asset search has the option to choose all Windows, All workstations, or a specific flavor, this would be on the script page, above the script window. Cuts down the complexity of the script needed, human error potential, and prevents unnecessary script runs on the asset. I hope I’m explaining this well enough, sometimes the logic gets so complex in a script when it could have easily been handled by Syncro when the data existed inside of Syncro. We can do some things with platform variables, but not enough.

Something you can do with platform variables is a customer name check, however, you still have to put the logic in the script, which means it has to run a PS1 on the asset to check the name in Syncro’s database. Instead, pre-run, if Customer = x,y, or z, run or do nothing.

This example could be fixed if assigned contacts on assets were indexed, but I have a script with a platform variable of the contact, then in the script it sets the contact to a custom field so that when I search, it pulls up the asset. Seems silly that something that is all internal needs to run a PS1 at all. Stuff like that is what I mean by offline scripts, something like that shouldn’t even need the asset online at all.

I can script around users and make the script do what I want. If I have to get creative and trigger alerts and use ARs etc there are some recovery/escalation options there. But this is really arround handling cases where either a script would just check status and exit (it never needed to hit the script queue in the first place), OR Syncro fails the script before my logic ever gets to process.

Honestly though I don’t have any example scripts that I care who they run under. Even the ones I thought of writing and never did due to run reliability issues would have been to set stuff that should be set for every user on a system so it doesn’t really matter who logs in… just needs to run under logged in users.

@jordanritz, you gave me an interesting thought though. If Last User was available in scripting, you could tailor scripts to specific users on a machine. I don’t have a use case, but I’m sure there are special instances where someone may want to do this. But by having the logic pre-script, it wouldn’t need to run scripts on the asset unnecessarily, and also would be less complex overall.

Ok that makes sense then.

This would mean that field would need to be updated in real time, otherwise I assume you’d get unexpected results quite often. This goes to the architectural stuff around running scripts and/or assigning policies are a dynamic grouping of assets (which is what this is really doing).

That is interesting. The one challenge with logged in user based pre-script checks is Syncro would actually have to do a real-time check to see if there was a user, or if there was a specific user before running the script as the platform does not keep any of that data up to date in close enough to real time not to end up with odd failures when it thinks a user is signed in but they signed out since the last sync etc.

  • lol Andy beat me to it

Right, but we’re getting off topic with what the request was. Two ways to handle logic, Syncro handles it and either runs the script or aborts, or Syncro always runs and logic is handled in the script. In summary, my request was to have Syncro handle at least some portion of logic and stop unnecessary script runs on the asset and also would be easier to build scripts. In all honesty, Syncro should be tracking logged in user in real-time, just as it should be updating some other fields either real-time or with certain triggers, but that’s for another topic.

Lol :slight_smile:

1 Like

Yeah, I think this is really the same request as running scripts against dynamic groups of assets. The architecture required is virtually identical, we’d just typically be scanning for a few more fields as part of a dynamic group, but the logic is virtually identical. I like the idea overall, but the architectural needs here are quite high is all.

I don’t really see it as the same. The script would only be checking the info about the asset it ran on against something in the database.

I assumed you were talking about running scripts in bulk. Like run against all assets only if they are X and Y.

This is logic for all scripts. Would even benefit setup scripts to only run setup on those it applies to without building it into the script itself, but yeah I can see how it could be crossing over into group territory, but that I think requires different architecture. So let’s try another scenario. I created a new policy for Acronis to monitor backup jobs. I then had to go into each customer and apply it to the appropriate machines. Instead, if Syncro made the application list available, it could check if Acronis is installed, then run, if not, do nothing. Whereas a dynamic group is processing a lot more, checking fields, moving assets in and out of groups as they meet criteria. Script logic is only checking static info about that asset.

Another example I just thought of, my install scripts that use platform variables for keys. In my script, I have it set to check if that field is null, if it is, it errors and aborts. Instead of needing for it to run the PS1 to do this, Syncro handles this and doesn’t run the script if it doesn’t have the field populated.

Logic-wise we’re really talking about the same thing. It’s scanning a group of assets for whatever criteria (in this case scoped to a customer with Acronis installed) and then processing scripts where applicable.

If we were to ever do this, we would definitely just go the dynamic group method as that would really solve all use cases for the most part. I do like this concept in general, it’s just likely not something we’re going to be tackling any time in the near future.

I don’t think I’m conveying the right message. I’ve had both dynamic groups and this, and they aren’t always used the same way. Part of it is cutting down the complexity of the code.
My reboot script, I check a platform variable to see if reboots are disabled. This would be simple in Syncro to just use the UI to say if this platform variable is true, abort, instead, I have to use if ($rebootdisabled -eq “no”). This one isn’t that complex, but you still have to get the syntax right. PS was a learning curve for me when moving to Syncro. Both CWA and Kaseya script builders were a lot more noob friendly.

Reboot pending script

Import-Module $env:SyncroModule -DisableNameChecking

$RebootPending = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' -ErrorAction Ignore
$RebootRequired = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' -ErrorAction Ignore
$PendingFileRenameOperations = $null -ne (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction Ignore)

if ($RebootPending -or $RebootRequired -or $PendingFileRenameOperations) {
    Write-Host "Reboot Pending: $RebootPending "
    Write-Host "Reboot Required: $RebootRequired"
    Write-Host "Pending File Rename Operations: $PendingFileRenameOperations"
    Write-Host "Rebooting..."
    shutdown /g /f /t 60
}
else {
    Write-Host "No reboot required"
}

More complex, this could be simplified by Syncro handling If Reboot Pending is false, then abort, and in the script, the only things listed are a write-host and the shutdown line.