Skip to main content

How are y’all handling the new iWork apps?

  • January 29, 2026
  • 4 replies
  • 219 views

john_sherrod
Forum|alt.badge.img+17

Now that here are all new Keynote, Pages, and Numbers app that have Premium features locked behind a subscription model, I’m curious how everyone is handling that. We’ve always automatically installed those apps on ever Mac, and Keynote is very heavily used within our organization.

If we do nothing, users are locked into version 14.5 forever and never get any new features or bug fixes. We could optionally deploy both 14.5 AND 15.1, but it’s gross having two versions of each app installed. Or, we can rip the bandaid off and remove the old version and deploy the new version to everyone.

Tradeoffs everywhere! Interested in learning what others are doing or considering doing.

4 replies

Jordy-Thery
Forum|alt.badge.img+14
  • Valued Contributor
  • January 30, 2026

There’s been quite some chatter on Slack about this topic.

Check out https://soundmacguy.wordpress.com/2026/01/28/keynote-numbers-and-pages-15-1-now-unified-across-all-apple-operating-systems/ & https://soundmacguy.wordpress.com/2026/01/29/suppress-the-upgrade-dialog-for-keynote-numbers-and-pages/ & https://scriptingosx.com/2026/01/managing-iwork-in-2026-the-creator-studio-update/

We ripped the bandaid as you said and deployed the new apps. You can perform some clean-up with a quick script. 

#!/bin/bash
set -e

remove_if_exists() {
  local creator_app="$1"
  local target_app="$2"

  if [[ -d "$creator_app" ]]; then
    if [[ -d "$target_app" ]]; then
      echo "Found: $creator_app"
      echo "Removing: $target_app"
      sudo rm -rf "$target_app"
    else
      echo "Target not found: $target_app (nothing to remove)"
    fi
  else
    echo "Not found: $creator_app (skipping)"
  fi
}

remove_if_exists "/Applications/Pages Creator Studio.app"   "/Applications/Pages.app"
remove_if_exists "/Applications/Numbers Creator Studio.app" "/Applications/Numbers.app"
remove_if_exists "/Applications/Keynote Creator Studio.app" "/Applications/Keynote.app"

echo "Done. Updating inventory to Jamf..."
jamf recon
exit 0

I think ​@Armin summarized it very well: 

“If you are deploying the apps formely known as iWork (Keynote, Pages, Numbers), you need to do the following:

  • ensure that the clients receive the 14.5 update, so that the settings that are transferred, can be transferred properly, when the new version is launched
  • once all clients have the 14.5 version, disable the deployment of the old versions
  • add licenses for the new apps to your volume purchasing in Apple Business or School Manager
  • configure your device management service to deploy the new apps, if your management service allows this, you may have to search for the new apps using the full app store link, as these are not Mac apps, but universal app entries in the App Store
  • scope the deployment to those clients that have the 14.5 version
  • if your device management service can add an AppConfig or Managed Application Configuration to a Mac App Store app deployment, add the showPrompts key with a value of true.
  • once the new version is installed, remove the old applications from the client
  • if you are managing the dock, replace any items in the dock to match the new app file paths”

john_sherrod
Forum|alt.badge.img+17
  • Author
  • Valued Contributor
  • January 30, 2026

Thanks! That armin blog post gave me some good ideas.

I need to rip the bandaid on this too. I’ve been feeling like Kylo Ren praying to Darth Vader’s melted helmet: “I know what I have to do, but I’m not sure I have the strength to do it.” 😂


LysetteB
Forum|alt.badge.img+16
  • Community Manager
  • January 30, 2026

@arminBriegel ‘s wisdom strikes again! ​@john_sherrod fantastic comparison 🤣


john_sherrod
Forum|alt.badge.img+17
  • Author
  • Valued Contributor
  • January 30, 2026

Ok, friends. I spent all day and a bunch of trial and error on a script. I did one for each of the three apps, but you could alternatively use policy parameters to just replace the words as needed. This script uses dockutil to replace the old Keynote app with the new Keynote app in the Dock for both the end user and our local admin user, and then removes both dockutil (since we don’t leave it on endpoints) and

#!/bin/zsh

# Replace legacy Apple Keynote with Keynote Creator Studio in-place
# for the currently logged-in console user AND the 'ladmin' account.
# Also removes legacy /Applications/Keynote.app after Dock updates.
# Uses --replacing 'Keynote' to preserve position when possible (label-based).
# Skips Dock changes if legacy app is not installed (avoids stale/ghost entries).
# Gracefully handles "already exists" during add.
# Only restarts Dock if changes were made to the console user's Dock.
#
# Updated for dockutil 3.0.2+ (Swift version)
# John Sherrod - v2.3 - January 30, 2026

###############################################################################
# Preconditions
###############################################################################

if ! command -v dockutil >/dev/null 2>&1; then
echo "ERROR: dockutil not found at runtime"
exit 1
fi

if [[ "$(dockutil --version)" != *"3."* ]]; then
echo "WARNING: This script is optimized for dockutil 3.x (you have $(dockutil --version))"
fi

###############################################################################
# Determine logged-in user
###############################################################################

loggedInUser=$(scutil <<< "show State:/Users/ConsoleUser" \
| awk '/Name :/ && ! /loginwindow/ { print $3 }')

if [[ -z "$loggedInUser" || "$loggedInUser" == "loginwindow" ]]; then
loggedInUser=""
echo "No logged-in console user detected. Will process ladmin only."
fi

###############################################################################
# Fixed admin user to always process
###############################################################################

ADMIN_USER="ladmin"

###############################################################################
# App paths and identifiers
###############################################################################

NEW_KEYNOTE="/Applications/Keynote Creator Studio.app"
OLD_KEYNOTE="/Applications/Keynote.app"
OLD_BUNDLE_ID="com.apple.iWork.Keynote"
OLD_LABEL="Keynote" # Visible label in Dock for legacy Keynote (adjust if localized/renamed)

if [[ ! -d "$NEW_KEYNOTE" ]]; then
echo "New Keynote app not found at $NEW_KEYNOTE. Exiting without changes."
exit 0
fi

###############################################################################
# Function to process a single user
###############################################################################

process_user() {
local targetUser="$1"
local plistPath="/Users/$targetUser/Library/Preferences/com.apple.dock.plist"
local isConsole=$( [[ "$targetUser" == "$loggedInUser" ]] && echo "yes" || echo "no" )
local changesMade=0

if [[ ! -f "$plistPath" ]]; then
echo "Dock plist not found for $targetUser at $plistPath — skipping."
return
fi

# If legacy Keynote.app is gone, assume any Dock entry is stale → skip replacement
if [[ ! -d "$OLD_KEYNOTE" ]]; then
echo "Legacy Keynote.app not installed for $targetUser — skipping Dock replacement (stale entries ignored)."
# Optional: Clean ghost entries if desired
# dockutil --remove "$OLD_BUNDLE_ID" --no-restart "$plistPath" 2>/dev/null
return
fi

find_output=$(dockutil --find "$OLD_BUNDLE_ID" "$plistPath" 2>/dev/null)
if [[ -n "$find_output" ]]; then
echo "Legacy Keynote found in Dock for $targetUser — replacing with --replacing '$OLD_LABEL'…"

# Use --replacing to try preserving position (label match required)
replace_result=$(dockutil --add "$NEW_KEYNOTE" --replacing "$OLD_LABEL" --no-restart "$plistPath" 2>&1)
replace_exit=$?

if [[ $replace_exit -eq 0 ]]; then
((changesMade++))
echo "Replacement successful (position preserved if label matched)."
elif echo "$replace_result" | grep -qi "already exists in dock"; then
echo "New Keynote (Keynote Creator Studio) already exists in Dock — no change needed."
else
echo "Replacement attempted but returned non-zero: $replace_result"
# Fallback: try plain add if --replacing failed for other reasons
add_result=$(dockutil --add "$NEW_KEYNOTE" --no-restart "$plistPath" 2>&1)
if [[ $? -eq 0 ]]; then
((changesMade++))
echo "Fallback add successful (appended to end)."
elif echo "$add_result" | grep -qi "already exists in dock"; then
echo "New Keynote already in Dock (fallback) — no change needed."
else
echo "Fallback add failed: $add_result"
fi
fi

if [[ $changesMade -gt 0 ]]; then
echo "Changes applied for $targetUser."
if [[ "$isConsole" == "yes" ]]; then
echo "Restarting Dock for console user $targetUser…"
killall Dock 2>/dev/null || true
else
echo "(Dock restart not needed for non-logged-in user $targetUser — changes apply on next login.)"
fi
else
echo "No effective changes made for $targetUser (likely already up to date)."
fi
else
echo "Legacy Keynote (bundle $OLD_BUNDLE_ID) not found in Dock for $targetUser — no changes needed."
fi
}

###############################################################################
# Process users
###############################################################################

if [[ -n "$loggedInUser" ]]; then
echo "Processing console user: $loggedInUser"
process_user "$loggedInUser"
fi

echo "Processing admin user: $ADMIN_USER"
process_user "$ADMIN_USER"

###############################################################################
# Cleanup: remove dockutil binary (optional)
###############################################################################

if [[ -x /usr/local/bin/dockutil ]]; then
echo "Cleaning up dockutil binary…"
rm -f /usr/local/bin/dockutil
fi

###############################################################################
# Cleanup: remove legacy Keynote.app (one-time, system-wide)
###############################################################################

if [[ -d "$OLD_KEYNOTE" ]]; then
echo "Removing legacy Keynote.app at $OLD_KEYNOTE…"
rm -rf "$OLD_KEYNOTE"
if [[ $? -eq 0 ]]; then
echo "Legacy Keynote.app successfully removed."
else
echo "WARNING: Failed to remove $OLD_KEYNOTE (permissions or in use?)."
fi
else
echo "Legacy Keynote.app already not present at $OLD_KEYNOTE — no removal needed."
fi

exit 0

the old Keynote app.