Skip to main content
Solved

Custom Patch Management Workflow


Did this topic help you find an answer to your question?
Show first post

112 replies

Forum|alt.badge.img+9
  • Valued Contributor
  • 135 replies
  • September 18, 2019

@tlarkin Love your work and the jamf helper looks great in dark mode but prefer the native notification feel from Alerter.


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • September 18, 2019

@myronjoffe yup many ways to do it, I have found that dialog boxes tend to get actually used more than notification center pops. Most of the people at my Org respond best to Slack, average to pop ups, and they ignore NC pretty much.

So, we are actually looking at getting rid of desktop notifications and go into Slackbot DMs and responses instead.


Forum|alt.badge.img+9
  • Valued Contributor
  • 135 replies
  • September 18, 2019

That sounds awesome and very original. Would love to see a write up or presentation on that one day 😃


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • September 18, 2019

we are just now staring the planning process of getting data pipelines into our product, build an Ops platform on top of it, and one of the integrations will be Slackbot and we also have a help desk AI product, that we are integrating into Slack as well. If all goes well maybe in 2020 we might be looking to share/present some of this stuff. :-)


Forum|alt.badge.img+1
  • New Contributor
  • 9 replies
  • November 19, 2019

@kendalljjohnson Thanks for the script and workflow, first of all!

Now, I've done small changes basically in displaying texts and been testing this locally from my coding app or from command line. It works perfectly. Of course I had to create local variables with static values to replace jamf script variables ($4, $5, etc).

However, when I put back jamf variables, put it in jamf and run the policy, it doesn't work. I calls the update policy regardless of Chrome being open or not without any alert.

I also made a version with 'osascript' instead of 'alerter' to see if that was the issue but still no luck. (In my company having to use an external piece of software has to run through a long security process which is basically a pain in the a...)

I might be missing something when translating variables...
I'll post my scripts in different posts for clear reading I guess.
Thank you!


Forum|alt.badge.img+1
  • New Contributor
  • 9 replies
  • November 19, 2019

-Erased-


Forum|alt.badge.img+1
  • New Contributor
  • 9 replies
  • November 19, 2019

LOCAL VERSION:

#!/bin/bash

# If app is open, alert user with the option to quit the app or defer for later. If user chooses to install it will quit the app, trigger the installation,
# then alert the user the policy is complete with the option to reopen the app. If the app is not open it will trigger the installation without alerting
# Quit and Open path have 2 entries for the times you are quiting/uninstalling an old version of an app that is replaced by a new name (for example quiting Adobe Acrobat Pro, which is replaced by Adobe Acorbat.app)

################################DEFINE VARIABLES################################

# $4 = Title
# $5 = App ID
# $6 = Process Name
# $7 = Jamf Policy Event
# $8 = Quit App Path
# $9 = Open App Path

title="Critical update"
subTitle="Google Chrome"
appID="com.google.com"
procName="Google Chrome"
policyID="install_GoogleChromeUpdate"
quitAppPath="/Applications/Google Chrome.app"
openAppPath="/Applications/Google Chrome.app"

#Defining the Sender ID as self service due to setting the Sender ID as the actual app being updated would often cause the app to crash
sender="com.jamfsoftware.selfservice.mac"
#Jamf parameters can't be passed into a function, redefining the app path to be used within the funciton
quitPath="$quitAppPath"
openPath="$openAppPath"

################################SETUP FUNCTIONS TO CALL################################

fGetCurrenUser (){
currentUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`

  # Identify the UID of the logged-in user
  currentUserUID=`id -u "$currentUser"`
}

fQuitApp (){
cat > /private/tmp/quit_application.sh <<EOF
#!/bin/bash

/bin/launchctl asuser "$currentUserUID" /usr/bin/osascript -e 'tell application "$quitPath" to quit'
EOF

/bin/chmod +x /private/tmp/quit_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/quit_application.sh"
/bin/rm -f "/private/tmp/quit_application.sh"
}

fOpenApp (){
  cat > /private/tmp/open_application.sh <<EOF
#!/bin/bash

/usr/bin/open "$openPath"
EOF

/bin/chmod +x /private/tmp/open_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/open_application.sh"
/bin/rm -f "/private/tmp/open_application.sh"
}

################################SETUP TIMER FILE################################

## Set up the software update time if it does not exist already
if [ ! -e /Library/Application Support/JAMF/$appID.timer.txt ]; then
  echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
fi

## Get the timer value
timer=`cat /Library/Application Support/JAMF/$appID.timer.txt`

################################ALERTER MESSAGE OPTIONS################################

saveQuitMSG="It must quit to be updated. Save all data before quitting."
updatedMSG="It has been updated. Thank you."
lastMSG="Please save your work and close $subTitle."

################################START 'UPDATE WITH ALERTER' PROCESS################################

# Look if app is open via process name
appOpen="$(pgrep -ix "$procName" | wc -l)"

# if the app is open and the defer timer is not zero
if [[ $appOpen -gt 0 && $timer -gt 0 ]]; then
    fGetCurrenUser
    updateAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$title: $subTitle" -message "$saveQuitMSG" -closeLabel "Defer ($timer)" -actions "Close & Update" -timeout 3600)"
    if [[ $updateAnswer == "Close & Update" ]]; then
        #quit app, install the update, then prompt the user when complete and ask if they want to reopen the app. Message will time out after 60 secs.
        fQuitApp

        /usr/local/bin/jamf policy -event "$policyID"
        reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$title: $subTitle" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
        if [[ $reopenAnswer == Reopen ]]; then
            fOpenApp
        fi
        #reset timer after updating
        echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

    else
        let CurrTimer=$timer-1
        echo "User chose to defer"
        echo "$CurrTimer" > /Library/Application Support/JAMF/$appID.timer.txt
        echo "Defer count is now $CurrTimer"
        exit 0
    fi
# if app is open and defer timer has run out
elif [[ $appOpen -gt 0 && $timer == 0 ]]; then
    fGetCurrenUser
    /bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$title" -message "$lastMSG" -actions "Close & Update" -closeLabel "No Deferrals Left " -timeout 3600
    fQuitApp

    /usr/local/bin/jamf policy -event "$policyID"
    reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$title: $subTitle" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
    if [[ $reopenAnswer == Reopen ]]; then
        fOpenApp
    fi
    #reset timer after updating
    echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

else
    # app is not open, reset timer and run updates
    echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
    /usr/local/bin/jamf policy -event "$policyID"
fi

Forum|alt.badge.img+1
  • New Contributor
  • 9 replies
  • November 19, 2019

JAMF VERSION:

#!/bin/bash

# If app is open, alert user with the option to quit the app or defer for later. If user chooses to install it will quit the app, trigger the installation,
# then alert the user the policy is complete with the option to reopen the app. If the app is not open it will trigger the installation without alerting
# Quit and Open path have 2 entries for the times you are quiting/uninstalling an old version of an app that is replaced by a new name (for example quiting Adobe Acrobat Pro, which is replaced by Adobe Acorbat.app)

################################DEFINE VARIABLES################################

# $4 = Title
# $5 = App ID
# $6 = Process Name
# $7 = Jamf Policy Event
# $8 = Quit App Path
# $9 = Open App Path

#title="Critical update"
#subTitle="Google Chrome"
#appID="com.google.com"
#procName="Google Chrome"
#policyID="install_GoogleChromeUpdate"
#quitAppPath="/Applications/Google Chrome.app"
#openAppPath="/Applications/Google Chrome.app"

#Defining the Sender ID as self service due to setting the Sender ID as the actual app being updated would often cause the app to crash
sender="com.jamfsoftware.selfservice.mac"
#Jamf parameters can't be passed into a function, redefining the app path to be used within the funciton
quitPath="$8"
openPath="$9"

################################SETUP FUNCTIONS TO CALL################################

fGetCurrenUser (){
currentUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`

  # Identify the UID of the logged-in user
  currentUserUID=`id -u "$currentUser"`
}

fQuitApp (){
cat > /private/tmp/quit_application.sh <<EOF
#!/bin/bash

/bin/launchctl asuser "$currentUserUID" /usr/bin/osascript -e 'tell application "$quitPath" to quit'
EOF

/bin/chmod +x /private/tmp/quit_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/quit_application.sh"
/bin/rm -f "/private/tmp/quit_application.sh"
}

fOpenApp (){
  cat > /private/tmp/open_application.sh <<EOF
#!/bin/bash

/usr/bin/open "$openPath"
EOF

/bin/chmod +x /private/tmp/open_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/open_application.sh"
/bin/rm -f "/private/tmp/open_application.sh"
}

################################SETUP TIMER FILE################################

## Set up the software update time if it does not exist already
if [ ! -e /Library/Application Support/JAMF/$appID.timer.txt ]; then
  echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
fi

## Get the timer value
timer=`cat /Library/Application Support/JAMF/$appID.timer.txt`

################################ALERTER MESSAGE OPTIONS################################

saveQuitMSG="It must quit to be updated. Save all data before quitting."
updatedMSG="It has been updated. Thank you."
lastMSG="Please save your work and close $5."

################################START 'UPDATE WITH ALERTER' PROCESS################################

# Look if app is open via process name
appOpen="$(pgrep -ix "$6" | wc -l)"

# if the app is open and the defer timer is not zero
if [[ $appOpen -gt 0 && $timer -gt 0 ]]; then
    fGetCurrenUser
    updateAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$saveQuitMSG" -closeLabel "Defer ($timer)" -actions "Close & Update" -timeout 3600)"
    if [[ $updateAnswer == "Close & Update" ]]; then
        #quit app, install the update, then prompt the user when complete and ask if they want to reopen the app. Message will time out after 60 secs.
        fQuitApp

        /usr/local/bin/jamf policy -event "$7"
        reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
        if [[ $reopenAnswer == Reopen ]]; then
            fOpenApp
        fi
        #reset timer after updating
        echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

    else
        let CurrTimer=$timer-1
        echo "User chose to defer"
        echo "$CurrTimer" > /Library/Application Support/JAMF/$appID.timer.txt
        echo "Defer count is now $CurrTimer"
        exit 0
    fi
# if app is open and defer timer has run out
elif [[ $appOpen -gt 0 && $timer == 0 ]]; then
    fGetCurrenUser
    /bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4" -message "$lastMSG" -actions "Close & Update" -closeLabel "No Deferrals Left " -timeout 3600
    fQuitApp

    /usr/local/bin/jamf policy -event "$7"
    reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
    if [[ $reopenAnswer == Reopen ]]; then
        fOpenApp
    fi
    #reset timer after updating
    echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

else
    # app is not open, reset timer and run updates
    echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
    /usr/local/bin/jamf policy -event "$7"
fi

Forum|alt.badge.img+16
  • Author
  • Valued Contributor
  • 105 replies
  • November 19, 2019

@federico.joly Hmm, not sure exactly where the issue would fall.

Without being able to test your exact process or changes, what I might suggest is adding in lines to echo out comments of each step in the process, including echoing out the variables. This might help see if it is not properly interpreting the variables, where things are getting stuck, or what actions might be getting skipped.

For example, quick lines such as echo "Process Name: $procName" right before it is supposed to check what process is running and echo "App open: $appOpen" to see if it is properly detecting the app. After running this you can then look in your Jamf logs to see what isn't translating correctly.

Hope that helps!


Forum|alt.badge.img+1
  • New Contributor
  • 9 replies
  • November 20, 2019

@kendalljjohnson thanks again!

I've been going around this for about a week and I had "Google Chorme" instead of "Google Chrome" in my policy, on the script parameters...

Sure, you all can call me names...

:'D


rqomsiya
Forum|alt.badge.img+12
  • Honored Contributor
  • 225 replies
  • December 20, 2019

Has anyone had any luck with Alterer and Catalina?


Forum|alt.badge.img+16
  • Author
  • Valued Contributor
  • 105 replies
  • December 20, 2019

@rqomsiya Yes, you have to change the App calling alerter (sender) to be an Apple App, not 3rd party like Self Service.

I am using the App Store, com.apple.AppStore, just so it shows the generic App Store logo, seemed the most generic that could apply to a broad spectrum of apps that might be notified for.


rqomsiya
Forum|alt.badge.img+12
  • Honored Contributor
  • 225 replies
  • December 21, 2019

Thanks @kendalljjohnson ill give that a shot!


Forum|alt.badge.img+3

Comment Removed (because I'm an idiot and now realize it)


Forum|alt.badge.img+8

Can someone try and show an working example for Catalina (with jamf)

I have the following that does not work and gives this error

pgrep: Cannot compile regular expression `' (empty (sub)expression)

#!/bin/bash

# If app is open, alert user with the option to quit the app or defer for later. If user chooses to install it will quit the app, trigger the installation,
# then alert the user the policy is complete with the option to reopen the app. If the app is not open it will trigger the installation without alerting
# Quit and Open path have 2 entries for the times you are quiting/uninstalling an old version of an app that is replaced by a new name (for example quiting Adobe Acrobat Pro, which is replaced by Adobe Acorbat.app)

################################DEFINE VARIABLES################################

# $4 = Title
# $5 = App ID
# $6 = Process Name
# $7 = Jamf Policy Event
# $8 = Quit App Path
# $9 = Open App Path


title="Critical update"
subTitle="Illustator"
appID="com.adobe.photoshop"
procName="Adobe Photoshop"
policyID="photoshopupdate"
quitAppPath="/Applications/Adobe Photoshop 2020/Adobe Photoshop 2020.app"
openAppPath="/Applications/Adobe Photoshop 2020/Adobe Photoshop 2020.app"

#Defining the Sender ID as self service due to setting the Sender ID as the actual app being updated would often cause the app to crash
sender="com.jamfsoftware.selfservice.mac"
#Jamf parameters can't be passed into a function, redefining the app path to be used within the funciton
quitPath="$8"
openPath="$9"

################################SETUP FUNCTIONS TO CALL################################

fGetCurrenUser (){
currentUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`

    # Identify the UID of the logged-in user
    currentUserUID=`id -u "$currentUser"`
}

fQuitApp (){
cat > /private/tmp/quit_application.sh <<EOF
#!/bin/bash

/bin/launchctl asuser "$currentUserUID" /usr/bin/osascript -e 'tell application "$quitPath" to quit'
EOF

/bin/chmod +x /private/tmp/quit_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/quit_application.sh"
/bin/rm -f "/private/tmp/quit_application.sh"
}

fOpenApp (){
    cat > /private/tmp/open_application.sh <<EOF
#!/bin/bash

/usr/bin/open "$openPath"
EOF

/bin/chmod +x /private/tmp/open_application.sh
/bin/launchctl asuser "$currentUserUID" sudo -iu "$currentUser" "/private/tmp/open_application.sh"
/bin/rm -f "/private/tmp/open_application.sh"
}

################################SETUP TIMER FILE################################

## Set up the software update time if it does not exist already
if [ ! -e /Library/Application Support/JAMF/$appID.timer.txt ]; then
    echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
fi

## Get the timer value
timer=`cat /Library/Application Support/JAMF/$appID.timer.txt`

################################ALERTER MESSAGE OPTIONS################################

saveQuitMSG="It must quit to be updated. Save all data before quitting."
updatedMSG="It has been updated. Thank you."
lastMSG="Please save your work and close $5."

################################START 'UPDATE WITH ALERTER' PROCESS################################

# Look if app is open via process name
appOpen="$(pgrep -ix "$6" | wc -l)"

# if the app is open and the defer timer is not zero
if [[ $appOpen -gt 0 && $timer -gt 0 ]]; then
        fGetCurrenUser
        updateAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$saveQuitMSG" -closeLabel "Defer ($timer)" -actions "Close & Update" -timeout 3600)"
        if [[ $updateAnswer == "Close & Update" ]]; then
                #quit app, install the update, then prompt the user when complete and ask if they want to reopen the app. Message will time out after 60 secs.
                fQuitApp

                /usr/local/bin/jamf policy -event "$7"
                reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
                if [[ $reopenAnswer == Reopen ]]; then
                        fOpenApp
                fi
                #reset timer after updating
                echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

        else
                let CurrTimer=$timer-1
                echo "User chose to defer"
                echo "$CurrTimer" > /Library/Application Support/JAMF/$appID.timer.txt
                echo "Defer count is now $CurrTimer"
                exit 0
        fi
# if app is open and defer timer has run out
elif [[ $appOpen -gt 0 && $timer == 0 ]]; then
        fGetCurrenUser
        /bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4" -message "$lastMSG" -actions "Close & Update" -closeLabel "No Deferrals Left " -timeout 3600
        fQuitApp

        /usr/local/bin/jamf policy -event "$7"
        reopenAnswer="$(/bin/launchctl asuser "$currentUserUID" /Library/Application Support/JAMF/alerter -sender "$sender" -title "$4: $5" -message "$updatedMSG" -closeLabel Ok -actions Reopen -timeout 60)"
        if [[ $reopenAnswer == Reopen ]]; then
                fOpenApp
        fi
        #reset timer after updating
        echo "3" > /Library/Application Support/JAMF/$appID.timer.txt

else
        # app is not open, reset timer and run updates
        echo "3" > /Library/Application Support/JAMF/$appID.timer.txt
        /usr/local/bin/jamf policy -event "$7"
fi

sdagley
Forum|alt.badge.img+25
  • Jamf Heroes
  • 3540 replies
  • May 25, 2020

@Captainamerica Don't quote the appOpen assignment. You should just have

appOpen=$(pgrep -ix "$6" | wc -l)

And to be pedantic, using backticks (`) for command substitution is considered a legacy usage, the recommended method is to use $(...).

e.g.

timer=`cat /Library/Application Support/JAMF/$appID.timer.txt`

should be

timer=$(cat /Library/Application Support/JAMF/$appID.timer.txt)

See SC2006 for more detail.


Forum|alt.badge.img+8

I managed to get it working

However, have 2 additional questions

If no more deferrals left the message appear. Is it possible to set a time limit, as it seems users can just ignore the message and nothing then will happen(of course this notification will stay there, but some users may just ignore this)

And 2nd question. As I can see it is only possible to have 1 policy running at a time (as far I have testet). So if I would push out a policy to photoshop, illustrator, indesign, I cannot do it in once, but I have to wait for each to finish before I can relaunch a new policy. Is it possible in the paramters to add more application so like $6 have photoshop; illustrator; indesign somehow ?


Forum|alt.badge.img+16
  • Author
  • Valued Contributor
  • 105 replies
  • May 26, 2020

@Captainamerica

-Alerter has a timeout option, -timeout, that can be used. Then you just use the if/else logic of if the alerter notification ends and the displayed options are selected then it performs the action you want.

-Never played with multiple instances at once. You could try adding & at the end of a command to tell the script to keep going, but I don't believe it would then be able to call an action back to Jamf after the script has been ended. Alternatively, you could potentially setup an array logic to cycle through multiple app titles, but that would probably take some reworking of the overall workflow and process within the policies.


Forum|alt.badge.img+8

Thanks.

Is there any possibility to have 2 policies running at same time but with different applications to close down ? Would also solve my problem and maybe more easy to set up ?


Forum|alt.badge.img+16
  • Author
  • Valued Contributor
  • 105 replies
  • May 29, 2020

@Captainamerica If you're referring to 2 policies from Jamf running at once on a machine, I don't believe that is possible. Multiple actions can happen within a single policy, but not simultaneously. Only method I can think of would be to locally store the script on the machine, but you might have to have a separate one for each app and fill in the variables of app titles. Then the policy could call on multiple of the local scripts, allowing Jamf to not be dependent upon the completion. You would still run into the "limitation" that only one policy can run at once, so if you have 2 different scripts attempting to run a jamf policy -event simultaneously one would fail. Maybe I'm missing another work around but that's what comes to mind right now.


Forum|alt.badge.img+8

I used the script and it works fine for adobe photoshop.
I used nearly 2 days now and I cannot get this working for Indesign and Illustrator for some reason, even I compare them the notification does not simply show up, even the application is open - so for some reason it does not work. The policy executes as was the application not running, but it is

It sounds really crazy as I can get both photoshop and also chrome working without issues


Forum|alt.badge.img+1
  • New Contributor
  • 6 replies
  • June 3, 2020

Adobe has dropped the 'CC' in the folder for Illustrator. The correct path would be '/Applications/Adobe Illustrator 2020/Adobe Illustrator.app' I think it's the same for InDesign.


Forum|alt.badge.img+8

@kendalljjohnson Can you try and post the current working scipt for Catalina

It is really driving me nuts right now. It worked so well for me to start with and even I tried start from scratch again it only shows the below picture when the policy is running - so there is no defer or quit option anymore, no matter which application I try with. So strange


Forum|alt.badge.img+1
  • New Contributor
  • 6 replies
  • June 4, 2020

Have you created a notification profile for Alerter (I used ProfileCreator) App bundle identifier is fr.vjeantet.alerter. I think it needs to be alert style banner


Forum|alt.badge.img+8

Well if it can show the banner it should work I think ?
Do you have a running config that works for Catalina ? - somewhere there must be a mistake in my since it does not show quit/defer option anymore, but just the picture in my post before


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings