8 votes

PowersHell and graph - setting SharePoint folder permissions help

Hello folks

Recently we've been playing with Powershell and having to move on to graph to do all the fancy things we want to achieve. MS forced this when they suddenly decided the MSOnline module was retired and things stopped working.

We've built a great New Team with SharePoint and including folders script. One of the things we used to do with the PNP module is set folder permission on two of the folders in a new team, making them only accessible to Owners. How the devil does one achieve this with Graph?

Any pointers would be grand.

11 comments

  1. [6]
    Galahad
    Link
    Just spit-balling here, but it looks like there are a few REST endpoints for what they're calling DriveItems. These look like logical resources that include SharePoint document libraries and...

    Just spit-balling here, but it looks like there are a few REST endpoints for what they're calling DriveItems. These look like logical resources that include SharePoint document libraries and folders.

    Within that, there is an Add Permissions endpoint. It looks like you gotta provide it a list of DriveRecipient objects, although the example seems to indicate you can just use an e-mail address?

    You're gonna need to figure out the IDs of the folders you're creating -- they're probably returned as part of the creation -- and feed those into this permissions endpoint, then provide e-mails or aliases along with the permissions you want to provide.

    At the risk of sounding like a broken record, I still recommend you leverage the REST endpoints directly over the out-of-the-box PSModules due to those dependency issues you were encountering last time (even though those examples do have a pwsh tab). It'll make your code more robust and it's good function-building practice.

    EDIT: Don't think I didn't notice that your spelling only includes a single capital letter this time. You'll come around :P

    5 votes
    1. [5]
      g33kphr33k
      Link Parent
      Thank you for the pointers. It's not just me writing the scripts, matter of fact, it's one of my seniors but coming from Bash and using PS modules to using pure Graph is... horrid? I think that...

      Thank you for the pointers.

      It's not just me writing the scripts, matter of fact, it's one of my seniors but coming from Bash and using PS modules to using pure Graph is... horrid? I think that about sums it up.

      1 vote
      1. [3]
        Galahad
        Link Parent
        You ought to do a write-up of it after you've figured it all out -- I'm curious to see how you solve it

        You ought to do a write-up of it after you've figured it all out -- I'm curious to see how you solve it

        1 vote
        1. [2]
          pjenroute
          Link Parent
          hello there, first, thank you very much! I am the other person wrapped up in this silliness. You pointed me in the correct direction. The situation was wanting to use graph and powershell to...

          hello there, first, thank you very much! I am the other person wrapped up in this silliness.
          You pointed me in the correct direction.
          The situation was wanting to use graph and powershell to create a folder structure and then block permissions on certain folders.
          The key was in the Add Permissions link you sent.
          I'm using the Invoke-MgInviteDriveItem module and found setting the retainInheritedPermissions parameter false removes all existing permissions "when sharing for the first time". I found this only works though if i set the sendInvitation parameter to true. Since the "owner" of the team is who i want to be able to see the hidden folders, it works out to be easier and i decided i dont mind if they get a message saying it's there and only for you.
          I basically build the payload based on the link you sent:
          $parms = @{
          recipients = @(
          @{
          email = "$TeamOwnerEmail"
          }
          )
          message = "Verbiage Verbiage Verbiage "
          requireSignIn = $true
          sendInvitation = $true
          retainInheritedPermissions = $false
          roles = @(
          "write"
          )
          }
          then i push those parms as the -BodyParameter using Invoke-MgInviteDriveItem along with the -DriveId and -DriveItemId

          Again, super grateful for the help. Thanks so much

          1 vote
          1. Galahad
            Link Parent
            Happy to hear it -- like I was mentioning before, those cmdlets are probably automatically generated based on a Swagger doc or something from the REST endpoints. If you end up running into those...

            Happy to hear it -- like I was mentioning before, those cmdlets are probably automatically generated based on a Swagger doc or something from the REST endpoints. If you end up running into those module dependency issues again, the nice thing is you're already 70% of the way to integrating directly with those REST endpoints. The only major hurdle left would be to implement the authentication and token handling.

      2. joshtransient
        Link Parent
        There does now also exist a CLI for Graph package, which may be slightly more favorable if PWSH isn't your primary skillset. Fair warning, it's fresh out of the oven, and has less documentation...

        There does now also exist a CLI for Graph package, which may be slightly more favorable if PWSH isn't your primary skillset. Fair warning, it's fresh out of the oven, and has less documentation out there than the PWSH modules.

        https://learn.microsoft.com/en-us/graph/cli/installation

        You are spot on about the autogenerated commands, save for the Swagger part. MSFT just had to be different, and the metadata for Graph API is in some god-forsaken XML format that can't be interpreted by OpenAPI or Swagger consumers. So they developed something called AutoREST to do the translation since by the time the Graph PG got around to writing modules, it was five years after v1 was released, and they sure as shit couldn't tell humans to document the thousands of endpoints available.

        << rant energy incoming, not directed at anyone in the comments, only at MSFT for putting software with 1998-era limitations in the fucking cloud >>
        Trying to do complicated folder structures in SPO with sharing links…let me tell you, someone pulled that dumb shit with a massive doc library I work with that should generally be open access to all. But since sharing links don't actually grant permissions to a user until the user clicks the link, there's no easy way to traverse the library's folder structure unless I surface each of those links separately and click each one. It's a truly horrible experience.

        What is even horrible-r is setting up your libraries with deeply nested folder structures, each permissioned in their own special way. The only place inheritance should be broken in SPO is at the library level. Then, sharing links for scenarios where "oh dang, this one person needs read or write access to just this one file or folder and they aren't a member of one of the SharePoint groups on the site." There are too many ways to fuck up permissions in SharePoint already.

        1 vote
  2. [5]
    joshtransient
    Link
    Why are you not using PnP now? Graph sucks for setting traditional SharePoint permissions - it can create sharing links (the Add Permissions article u/Galahad mentioned) or grant permissions for...

    used to do with the PnP module

    Why are you not using PnP now? Graph sucks for setting traditional SharePoint permissions - it can create sharing links (the Add Permissions article u/Galahad mentioned) or grant permissions for ME-ID app registrations.

    Professional recommendation: stick with PnP for now. It'll do Teams stuff for you too, provided you give it the right permissions. It also handles the access token juggling for you, since SPO REST and Graph access tokens must be acquired separately.

    Direct REST API calls is the step up. PnP is inefficient as hell, but makes for nice, readable scripts.

    4 votes
    1. [2]
      Galahad
      Link Parent
      Yeah, that link in my comment says it sets permissions and optionally e-mails users about it, so I think that creating sharing links is definitely related, but maybe not quite the same thing?...

      Yeah, that link in my comment says it sets permissions and optionally e-mails users about it, so I think that creating sharing links is definitely related, but maybe not quite the same thing? Regardless, +1

      You can do it, u/g33kphr33k. Be brave, suck it up, and integrate directly with REST. You'll learn a lot

      3 votes
      1. g33kphr33k
        Link Parent
        It's not the same thing. We're essentially trying to access advanced permissions as you would in the file system. By default, MS turn on Owner and Members as Write to everything and inherited....

        It's not the same thing. We're essentially trying to access advanced permissions as you would in the file system. By default, MS turn on Owner and Members as Write to everything and inherited. What we're trying to achieve is turning off inheritance on a folder called Confidential, and allowing only Owners access. You can do this in the SharePoint GUI under advanced permissions, so it's definitely possible.

        This is different to "Sharing" permissions, which is about creating links to things for others to use. Essentially, it would enable those same permissions underneath, so maybe we could do that and set $email = false so it sets them, but it doesn't seem like it's quite the right way to do it. Also, knowing MS, they'll set a timeout on the permissions if done this way.

        1 vote
    2. [2]
      g33kphr33k
      Link Parent
      I wrote a lot of scripts a couple of years ago, and we've had to update them as we go. Suddenly, MSOnline went, then PNP broke for part of what we were doing with files and folders. After a bit of...

      I wrote a lot of scripts a couple of years ago, and we've had to update them as we go. Suddenly, MSOnline went, then PNP broke for part of what we were doing with files and folders.

      After a bit of research and a few very clever people stating that Graph is the way to go if you want to manipulate a lot of M365 functionality, I started with my colleague to rewrite a lot of what we wanted to do in graph and be damned with the other modules. You can also thank /u/Galahad for coaxing me along.

      We have our New User script working wonderfully, along with short_term_archive and a couple of other useful scripts. The big rewrite is Teams. We create a lovely folder structure, and we have that now, we had to go the API App way rather than delegated permissions to get that working. Now we're at the point of trying to break inheritance, and MS are not making this easy.

      1. joshtransient
        Link Parent
        PnP had a major change this year…versions 2.1.1 and newer require PowerShell 7 and don't really play nice with the Az modules. The last version that works with PS 5.1 is 1.12 and should still work...

        PnP had a major change this year…versions 2.1.1 and newer require PowerShell 7 and don't really play nice with the Az modules. The last version that works with PS 5.1 is 1.12 and should still work just fine. Can I ask specifically what broke for you?

        Graph API is in a weird place for people who need to manipulate EXO and SPO objects. It covers many user-facing scenarios, but can't do the real heavy lifting. Both of those services' native APIs do waaaay more and will be supported for many, many years to come. Product groups just keep dragging ass on closing the gap. The ME-ID team was forced to find a new scripting home since AzureAD and MSOnline will die with the shutdowns of Azure AD Graph and ADAL. One day. the same may be true of SPO CSOM/REST and EWS.

        Graph API is the future (or at least, that's the MSFT party line), so kudos to you for being proactive and moving over…a lot of ME-ID admins are gonna be fucked next year to put it lightly. However, until Graph can enable a feature or change a site's sharing capabilities, or do basic permissions inheritance breaking, stick with the "legacy" stuff. It'll be supported for years to come.

        2 votes