Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

PS linked objects script MacOS

Community Beginner ,
Sep 24, 2025 Sep 24, 2025

Hi folks,

 

TL;DR: I am trying to find (or create) a way to automatically relink all linked objects across multiple subfolders from a shared drive in a single PSD upon opening the file in Photoshop CC for MacOS.

 

Long version: I work in a studio where PS files must be shared between a team of artists and many of us touch the files at different points in the process. We have container PSDs with multiple linked objects in each, and the source files for the linked objects are stored on a shared Google Drive. MacOS changes the base directory for the shared drive to each person's username and Google Drive has its own credentials, so that even when the relative folder placement remains the same (ex. SharedDrive/Folder/Workfiles/Example.psd) the absolute path changes upstream from the files, forcing each artist to relink all the files manually at open. (ex. Users/NameNameson/Library/CloudStorage/GoogleDrive-namenameson@companyname.com/SharedDrive/Folder/Workfiles/Example.psd)

We have different asset types organized into different folders on the shared drive, but once created, the relative file structure within the project folder does not change. The automatic dialog only works to relink files in the same folder and the process must be repeated for each folder that contains linked files. Our workflow does not currently use Photoshop Libraries, though if nothing else works, that might be an option if we can also get the library files to copy to Drive.

I've looked through lots of posts describing similar issues here, on reddit, and on github, and cannot find a solution for this problem. I've already tried this script and its update (https://community.adobe.com/t5/photoshop-ecosystem-ideas/is-there-an-option-that-shows-me-a-list-wit...) and while it finds the broken links without an issue, I cannot get it to update them. jazz-y mentioned that one part of it only works on Windows and that may be hanging the rest of the function for me on Mac.

 

Is it even possible to change PS relink behavior to look only at relative file paths, or to specify the highest level directory that it should look in? Can this be scripted or controlled via an action? We're losing a lot of time tracking down source file locations when they should be known or (hopefully) automatically populated, and I would love to streamline the process.

TOPICS
Actions and scripting , macOS
254
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Sep 24, 2025 Sep 24, 2025
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 24, 2025 Sep 24, 2025

Thanks, there are some discussions here I hadn't found!

I did try the previous script you posted in the same thread as the jazz-y one, and it gave me an error 8800 (screenshot attached if it helps.)

The rest of the scripts I've tried, as well as PS default, can't handle the different subfolders. Even though those should be consistent between users.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 24, 2025 Sep 24, 2025

So just to confirm, when you open such a PSD, there may be linked smart objects such as:

 

/gdrive/jack/headers/header1.psd

 

However, when you open the PSD, the you need the linked asset to read as:

 

/gdrive/lysandra/headers/header1.psd

 

Where you need to update the entire path in blue, with the path on your machine in red. I'm guessing it's not going to be that simple though.

 

Can you please post some examples so that I can see that actual pattern of the link, which bits change and which bits are unchanged?

 

If the path is always the same for each user, it could either be configured via a settings file, or perhaps the script could offer the user to select the main path or perhaps the first new file that matches, then it could use this as an example for the other missing links.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 24, 2025 Sep 24, 2025

Thank you for your super quick responses, Stephen!

Here is the whole file path with just the parts that change between users highlighted:

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.0123@abcompany.com/Shared drives/Dev/Projects/Gamename/BGFolder/BG_01.psd

/Users/jack/Library/CloudStorage/GoogleDrive-jack.4567@abcompany.com/Shared drives/Dev/Projects/Gamename/BGFolder/BG_01.psd

 

What would be ideal is some way to instruct PS to look only at the /Shared drives/Dev/Projects/Gamename/BGFolder/BG_01.psd part.

However, /BGFolder/ is just one of the folders with linked assets in it. One container PSD might have links to multiple assets in /BGFolder/, /CharacterFolder/, /UIFolder/, etc. Like the following:

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/BGFolder/BG_01.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/BGFolder/BG_02.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/BGFolder/BG_03.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/CharacterFolder/CharacterExpression_01.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/CharacterFolder/CharacterExpression_02.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/UIFolder/UIFrame.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/UIFolder/UIElement_01.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/UIFolder/UIElement_02.psd

/Users/lysandra/Library/CloudStorage/GoogleDrive-lysandra.lastname@ABCompany.com/Shared drives/Dev/Projects/Gamename/UIFolder/UIElement_03.psd

 

The path is always the same structure for each user and we are all pulling linked assets from the same shared database. Being able to select the main path or the /Gamename/ directory would be the best option, as right now the auto relink dialog gets caught up in the subfolders.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 24, 2025 Sep 24, 2025

@Lysandra26636147dc2x 

 

Are the following entries in red static for each user, or do they change?

 

lysandra.0123

jack.4567

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 24, 2025 Sep 24, 2025

Those are static for each user (the company e-mail address associated with the GDrive account for each employee)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2025 Sep 25, 2025
quote

Those are static for each user (the company e-mail address associated with the GDrive account for each employee)


By @Lysandra26636147dc2x

 

Please test the following snippet, it's only purpose is to confirm the path of a selected linked smart object layer.

 

It will copy the path to the clipboard, then you can paste the clipboard path into the forum.

 

Please test on at least two different computers and paste the link text and or screenshot of the alert here to confirm the path.

 

You can redact or change the company name, I just need to check that the preiously discussed static .digits suffix is correctly reported for each user.

 

/*
Snippet from:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-replacing-linked-smart-objects-based-on-layer-quot-name-string-quot/td-p/14559920
*/

var theName = getSmartObjectReference().filePath.fsName.toString();
alert(theName);

var d = new ActionDescriptor();  
d.putString(stringIDToTypeID("textData"), theName);  
executeAction(stringIDToTypeID("textToClipboard"), d, DialogModes.NO);

function getSmartObjectReference() {
    // https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
    try {
        var smartObject = {
            found: false,
            fileRef: '',
            filePath: '',
            linked: false,
        };
        var ref, so;
        ref = new ActionReference();
        ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
        smartObject.found = true;
        smartObject.linked = so.getBoolean(stringIDToTypeID("linked"));
        smartObject.fileRef = so.getString(stringIDToTypeID("fileReference"));
        if (smartObject.linked) {
            smartObject.filePath = so.getPath(stringIDToTypeID("link"));
        } else {
            smartObject.filePath = Folder.temp + '/' + smartObject.fileRef;
        }
        return smartObject;
    } catch (e) {
        alert(e);
        return smartObject;
    }
}

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 25, 2025 Sep 25, 2025

My colleague and I couldn't get this one to work. It would throw back one or both of the following (tested on PS 2023 and 2025), and nothing showed up on the clipboard.
 Screenshot 2025-09-25 at 12.53.32.pngScreenshot 2025-09-25 at 12.54.19.png

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2025 Sep 25, 2025

@Lysandra26636147dc2x 

 

I tested in v2021 and v2024 on the Mac, the script that failed for you works for me.

 

Thanks for letting me know about the error in  retrieving the full path of the linked smart object. I should be able to use different code and will test in a later version.

 

EDIT: Does the following script from @c.pfaffenbichler work for you?

 

// https://community.adobe.com/t5/photoshop-ecosystem-ideas/is-there-an-option-that-shows-me-a-list-with-all-smart-objects-paths/idi-p/12657491
// get list of linked smart objects’ paths;
// 2022, use it at your own risk;
var aaa = collectSmartObjectsLinks();
alert("\n" + aaa.join("\n\n") + "\n\n" + "(copied to clipboard)");

// SO linked paths to list
var list = aaa.join("\n");

// Copy SO linked paths list to clipboard
var d = new ActionDescriptor();
d.putString(stringIDToTypeID('textData'), list);
executeAction(stringIDToTypeID('textToClipboard'), d, DialogModes.NO);

// Text file platform specific LF options
var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
if (os === "mac") {
    textFileLF = "Unix"; // Legacy = "Macintosh"
} else {
    textFileLF = "Windows";
}
// Create a desktop text file of the SO linked paths
var textFile = new File('~/Desktop' + '/' + 'Linked SO Paths.txt');
if (textFile.exists)
    textFile.remove();
    textFile.open('w');
    textFile.encoding = 'UTF-8';
    textFile.lineFeed = textFileLF;
    textFile.write(list);
    textFile.close();
    
    // Open the text file
    textFile.execute();

////// collect layers //////
function collectSmartObjectsLinks() {
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array();
    for (var m = 0; m <= theNumber; m++) {
        try {
            var ref = new ActionReference();
            ref.putIndex(charIDToTypeID("Lyr "), m);
            var layerDesc = executeActionGet(ref);
            //var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
            //var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
            var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
            // collect smart object links;
            if (isSmartObject === true) {
                var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
                if (theSO.getBoolean(stringIDToTypeID("linked")) === true) {
                    var theLink = theSO.getPath(stringIDToTypeID("link"));
                    var theCheck = true;
                    for (var n = 0; n < theLayers.length; n++) {
                        if (theLayers[n] == String(theLink)) {
                            theCheck = false;
                        }
                    }
                    if (theCheck === true) {
                        theLayers.push(theLink.fsName);
                    }
                }
            }
        } catch (e) {}
    }
    return theLayers;
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2025 Sep 25, 2025

@Lysandra26636147dc2x 

 

Similar but different to the previous, code, I just want to confirm that the correct user and drive details are extracted/isolated:

#target photoshop

if ($.os.indexOf("Windows") !== -1) {
    alert("This script is only for the macOS Google Drive path!");
    throw new Error("Not intended for MS Windows...");
}

var homeFolder = getHomeFolder();
if (!homeFolder || !homeFolder.exists) {
    alert("Unable to resolve user home folder!");
    throw new Error("Home folder not found.");
}

var userName = homeFolder.fsName.match(/\/Users\/([^\/]+)$/);
userName = userName ? userName[1] : "Unknown";

var cloudStorage = new Folder(homeFolder + "/Library/CloudStorage");
if (!cloudStorage.exists) {
    alert("No GoogleDrive-* folder found!");
    throw new Error("CloudStorage folder does not exist.");
}

var googleDriveFolder = findGoogleDriveFolder(cloudStorage);
if (googleDriveFolder) {
    alert("Google Drive Info:\n" + userName + "\n\n" + googleDriveFolder.name);
} else {
    alert("No GoogleDrive-* folder found!");
}


function getHomeFolder() {
    var match = Folder.userData.fsName.match(/\/Users\/([^\/]+)\//);
    return match ? new Folder("/Users/" + match[1]) : null;
}

function findGoogleDriveFolder(baseFolder) {
    var folders = baseFolder.getFiles(function (f) {
        return f instanceof Folder && /^GoogleDrive-[^\/]+@[^\/]+$/.test(f.name);
    });

    return folders.length ? folders[0] : null;
}

 

If this works as expected, then the paths can be changed based on the user running the final script (which I haven't written yet).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 25, 2025 Sep 25, 2025

This version worked a treat for me! Waiting on my colleague to test on her machine and will report back.

Thank you so much for your help.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 25, 2025 Sep 25, 2025

Fetched the correct info on the first try for both me and my colleague, across PS 2023 and 2025. Nice!

ITWORKS.png

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2025 Sep 25, 2025

That's good to know that the second code is working as expected.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2025 Sep 25, 2025

@Lysandra26636147dc2x 

 

I will test using my Google Drive and Mac, however, I can't create the links from another account for testing.

 

Can you provide a layered test PSD file with links to 2 or more files, and also provide the linked files? I'll recreate the directory structure on my drive, but just in case, please paste an example of the link.

 

This only needs to be a mock file, not a production file that may contain client sensitive data. The layer structure should match a production file though (if you use layer sets or artboards etc). The actual content and resolution etc. doesn't matter, it's only the link paths that are important. You can send me a private message with the files to avoid having your email address out there in the publicly available files.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
2 hours ago 2 hours ago
LATEST

Thanks again. I have DMed you the test file and link path. Fingers crossed.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 26, 2025 Sep 26, 2025

@Lysandra26636147dc2x 

 

I just had a thought...

 

What happens if you use the properties panel and select "update modified content"?

 

I'm just trying to better understand the issue, if it is just picking up modified content or if it's really a broken link. Screenshots of the layers panel and properties panel would of course help.

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines