Kaseya Community

IF AND ELSE

This question is not answered

Hey guys I'm in a pickle creating a procedure. What I'm trying to do is verify that two registry keys are set the way they need to be. If they BOTH match the value 0 then it calls a different procedure. If they BOTH don't match then the procedure changes the values and THEN calls a different procedure.

The problem I'm running into is that I cannot think up a way to condense an IF statement to compare TWO different values and then make a decision on what to do next.

I'll put a snip of my mess in here. IGNORE THE "IF TRUE" AT THE BOTTOM. I was experimenting.  Pretty sure I need an ELSE statement for every IF but I'm not sure.. Sure seems like it though because  if there were an AND between the top two IF statements, this script should work just fine.

All Replies
  • It seems like you want to executeProcedure('Software Management - System Restore Point Creation *WORKSTATIONS ONLY*') regardless of the Registry Settings. If they aren't set, you want to set them, but ultimately, you want to run the procedure. Does this logic follow what you are trying to do?

  • To specifically answer your question without tying to glean what you want to do from the code, here is how you check two conditions. It gets trickier if you need different actions when the first condition is false, but the second condition is true.

  • How I have dealt with similar scenarios in the past is to use a bit of Math in the procedures

    So 1st create a variable to hold my registry test results

    e.g. #Global:Result# and set the initial value = 0

    Now when I run through the 1st IF and test the registry key if I get the result I want I set the variable to :

    #Global:Result# = 0 , if not I set to to 1

    Then Next IF checks next Reg Key and again if I get the result I want I set it to :

    #Global:Result# = #Global:Result#0

    or

    #Global:Result# = #Global:Result#1

    So at the end of the two IF steps I now have a variable that will be one of the following

    #Global:Result# = 00

    #Global:Result# = 10

    #Global:Result# = 01

    #Global:Result# = 11

    I can then add my own final IF statement that checks the variable and

    IF = 00 do nothing as everything is OK

    IF = 10 update RegKey 1

    IF = 01 update RegKey 2

    IF = 11 update both RegKeys

    You can do the same using some Base2 logic instead and use the GetVariable/Expression Value

    The difference being you are now actually mathematically adding the results

    So in the example above , and assuming you have a total of 3 IF statement ,  you start with a Default of 0 and the 1st IF adds 1 , the 2nd IF adds 2 , the 3rd IF adds 4

    The final variable result you will be one of these possible values

    #Global:Result# = 0  (means ALL IF's returned a 0 )

    #Global:Result# = 1  (means only the 1st IF returned a 0 )

    #Global:Result# = 2  (means only the 2nd IF returned a 0 )

    #Global:Result# = 3  (means both the 1st and 2nd IF returned a 0 )

    #Global:Result# = 4  (means only the 3rd IF returned a 0 )

    #Global:Result# = 5  (means both the 1st and 3rd IF returned a 0 )

    #Global:Result# = 6  (means both the 2nd and 3rd IF returned a 0 )

    #Global:Result# = 7  (means ALL IFs returned a 0 )

    Hope that makes sense

  • Thanks guys for the suggestions Jondle and Paul. Paul, I am a bit confused by how you explained it but I believe I understand the logic. What confused me is how you ended up with 7 on your last #Global:Result#. Why did the third variable jump to four instead of 3? Lol, thats probably irrelevant information so lets see if what I'm understanding will work.

    The main thing here is I just want to make sure both registry keys are set so that system restore is enabled. I don't need to add seperate code to distinguish which one is out of order and then fix it. I love figuring out code so it wouldn't mind taking a shot at that extra step but I don't think that there is a real benefit in investing the extra time into that, from a business stand point.

    The only reason I could justify it would be that overwriting an already set registry key repeatedly could hurt something some how.

    Anyway, let me know what you guys think of this chunk of pseudo-code.

    IF (key1) = 0

    Set #Global:Result# = 0

    Else

    Set #Global:Result# = 1

    IF (key2) = 0

    Set #Global:Result# = #Global:Result# + 0

    Else

    Set #Global:Result# = #Global:Result# + 1

    If #Global:Result# = 0

    Run next procedure

    Else

    Set (key1) = 0

    Set (key2) = 0

    Run next Procedure

  • The bit mask is a great and creative idea. I would stick to binary strings (ie. 1011001) instead of trying to convert to decimal (ie. 89) because Agent Procedures don't natively support math...or bitwise operations.

    Honestly , you would be better off just writing a PowerShell script to do the actual tests and work. Then just have your Agent Procedure:

    1) Write the script

    2) Execute the script

    3) Get results

    4) Write results to Agent Procedure Log

    The Agent Procedures interface is so tedious to debug and functionally limiting, you're just killing a lot of time.

  • Yeah I'm really getting frustrated. I've got everything created but I'm getting an incorrect logical answer... it's not mission critical but I'm a bit OCD when it comes to this kind of stuff. I get my variables set, test them to verify they are right - they are - then add them together but it comes out wrong. It seems that when I call getvariable to add key1 and key 2 to make keysum, it just plugs in whatever key2 is.. I created a seperate procedure with the same concept, works perfectly fine. GRRRR I wish I knew powershell better!!

  • I noticed procedures being finicky like that too. I have had to rebuild a script from scratch because it would run in one script but not another (yet they both do the same thing). You could create another script and have the original script call upon second one.

  • I didn't really test this, but see if this gets you started.

    $disableSR = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableSR

    $disableConfig = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableConfig

    if ($disableSR -eq 0 -and $disableConfig -eq 0) {

       'Both are 0' | Out-Host

    }

    elseif ($disableSR -eq 1 -and $disableConfig -eq 1) {

       'Both are 1' | Out-Host

    }

    elseif ($disableSR -eq 1) {

       'DisableSR = 1 and DisableConfig = 0'

    }

    else {

       'DisableSR = 0 and DisableConfig = 1'

    }

  • The reason I jump from 0,1,2 then to 4 is I am just building a decimal representation of a binary or "base2" result

    So it's basically the same

    0 = 00000000

    1 = 00000001

    2 = 00000010

    3 = 00000011  ( which = 1+2 )

    4 = 0000100

    5 = 0000101 ( which = 4+1

    6 = 0000110 ( which = 4+2

    7 = 0000111 ( which = 4+2+1

    8 = 0001000

    etc

    So see above how I don't actually need a '3'  or a 5 or 6 or 7 as I can derive these results based on the binary math of a 0,1,2,4,8 etc

    Hope that clarifies it

  • Man I have a lot to learn guys.. I'll test that out Jondle and see if I need to try to fix it or rework it. I'm not sure what the last ELSEIF chunk does. The whole script just basically tells me what is disabled and enabled correct? I'll just need to learn how to tie that VBscript into the procedure. I'm really unexperienced when it comes with working with variables, especially if I'm mixing platforms like CMD, powershell and cornerstone procedures.

    That makes more sense Paul, I'm not real up to speed with binary but I know enough for that to make sense. TY both of you.

  • That was PowerShell, not VBScript.

    It simply checks the two registry locations and outputs their current status. Since the first two if blocks check that both registry values are equal (either both 1 or both 0), it means that anything beyond that has values that are different. Therefore, you don't have to check both values in the third if block; they aren't equal, so if one of them is 1, the other must be 0. The else block doesn't need to test anything because the there are only 4 possibilities and we've checked the first three, it has to be the fourth.

    I intended you to replace the output strings with the action code you are looking for. Here is a decent write up about testing and setting registry values: blogs.technet.microsoft.com/.../update-or-add-registry-key-value-with-powershell

  • K, how does this look?

    $disableSR = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableSR

    $disableConfig = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableConfig

    if ($disableSR -eq 0 -and $disableConfig -eq 0) {

      'Both are 0' | Out-Host

    }

    elseif ($disableSR -eq 1 -and $disableConfig -eq 1) {

        New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableSR -Value 0

        New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableConfig -Value 0

      'Both are 1' | Out-Host

    }

    elseif ($disableSR -eq 1) {

      'DisableSR = 1 and DisableConfig = 0'

      New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableSR -Value 0

    }

    else {

      'DisableSR = 0 and DisableConfig = 1'

      New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableConfig -Value 0

    }

    I've confirmed that it works too. I would like to have it write something to the procedure log based on what it had to do. Any recommendations on how to do that?

  • It would work, but the logic is unnecessarily complex. My suggestion on cleaning it up after answering the output question.

    You can pipe strings to Out-File -FilePath 'C:\kworking\output.log' to write to a log file. Then in your Agent Procedure do:

    getVariable(File Content, 'C:\kworking\output.log', log)

    writeProcedureLog("Output: #log#")

    In my example, I added a Param($LogFile) block. This will allow you to pass a parameter upon execution. When executing the script for the Agent Procedure, use (assuming you set variables #scriptFile# and #logFile# earlier in the Agent Procedure):

    executeFile("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-nologo -executionpolicy bypass -file #scriptFile# -LogFile #logFile#")

    Back to cleaning up your code a little, there is no need to check if they are both 1 if you aren't going to do anything inside the if block. Also, if all you are doing is setting each value to 0 if it is currently 1, you don't need to check both simultaneously at all. Simply check one and set it if necessary, and then check the other and set it.

    Param (

       $LogFile

    )

    $disableSR = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableSR

    $disableConfig = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore').DisableConfig

    "Initial Settings: DisableDR = $disableSR, DisableConfig = $disableConfig" |  Out-File -FilePath $LogFile

    if ($disableSR -eq 1) {

       New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableSR -Value 0

       'Set DisableSR to 1' | Out-File -FilePath $LogFile -Append

    }

    if  ($disableConfig -eq 1) {

       New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore" -force -Name DisableConfig -Value 0

       'Set DisableConfig to 1' | Out-File -FilePath $LogFile -Append

    }