Uncategorized – Inquisitive M365 https://thomasdaly.net Yet another SharePoint / Office 365 blog Tue, 19 Sep 2023 19:16:54 +0000 en-US hourly 1 116451836 Passed – AZ-204 Developing Solutions for Microsoft Azure https://thomasdaly.net/2021/08/14/passed-az-204-developing-solutions-for-microsoft-azure/ https://thomasdaly.net/2021/08/14/passed-az-204-developing-solutions-for-microsoft-azure/#respond Sat, 14 Aug 2021 09:49:32 +0000 https://thomasdaly.net/?p=2617 On June 8, 2021 I passed my AZ-204 exam to become a Microsoft Certified Azure Developer Associate. I completed the exam on my first attempt after a month of studying. The majority of my knowledge came from working with Azure and developing over the past year. There are many free resources that are also available on youtube and Microsoft that were also helpful. Nothing beats having hands on, real world experience in preparation from these exams. This exam was not so easy as it requires to recall commands and code snippets from memory. I’m excited that I was able to pass and looking forward to continuing to develop my Azure knowledge and understanding.

]]>
https://thomasdaly.net/2021/08/14/passed-az-204-developing-solutions-for-microsoft-azure/feed/ 0 2617
PnP PowerShell V4 Provisioning with Azure Functions V3 and Power Automate / Flow https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/ https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/#respond Fri, 09 Apr 2021 17:56:16 +0000 https://thomasdaly.net/?p=2357 Introduction

Trying out the new way to Provision via PnP PowerShell V4 and Azure Functions V3 was a little challenging at first. There are some of the difference and issues that I encountered which I could not get to work correctly. I happen to be one of the early ones that need to do this because Azure had made a change to their interface which prevented using PnP PowerShell V3 and the Microsoft documentation was not updated. Since that time and now Microsoft has updated their online documentation with examples of the exact steps. I’ve decided to post the process I used to get everything working but I still suggest reading the official Microsoft article as well.

Install PnP.PowerShell

  1. Open PowerShell 7 (if not installed, please install from here – https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7.1)
  2. Run the following cmdlet to install the PnP.PowerShell module

Install-Module -Name "PnP.PowerShell" -RequiredVersion "1.5.0"

Set up app-only access to your tenant

  1. Open PowerShell 7 and run the following cmdlets to register an Azure App

Select the appropriate tenant name before running.

Register-PnPAzureADApp -ApplicationName "PnPProvisioningDemo" -Tenant "<tenant-name>.onmicrosoft.com" -DeviceLogin -OutPath .

Follow the instructions to complete the Azure AD App registration. You will need to open a browser and enter the url above and supply the code. You will also be asked to log in.

This will now take 60 seconds to create the certificate in the out path that was specified in the above command

  • After the cmdlet is executed. It will create a PFX file. Keep this file saved, as we will have to upload it to Azure function.
  • Login to https://aad.portal.azure.com/
  • Click -> Azure Active Directory -> App Registration
  • Search for ‘PnPProvisioningDemo’ and the select the App Registration which got created. Copy the Application (client) ID from here.
  • Click API Permission
  • Click API Permissions, and Grant admin consent for {tenant}
  • In the small popup click Yes to approve this app those permissions.

Create the Azure function

  • Type in ‘Function’ and select ‘Function App’
  • In the Project Details, click on Create New, for the Resource Group
  • Type in ‘PnPProvisioningDemo’ for the resource group name, click OK

  • Enter in a Function App name – this will need to be unique, Runtime Stack, Version and select a Region in which you want the resources inr its created, navigate to your new function App
  • From the dropdown menu, select host.json file and add the following entry and save it.
  • Click ‘Review + create’
  • Click ‘Create’

After a few moments all of the assets will be created.

  • Click ‘Go To Resource’
  • Next click on ‘App Files’
  • I typically bump the timeout to 10 mins for the Azure Function from the default 5 minutes.
  • In the App Files > host.json, add this line. Make sure to use a ‘,’ on the previous line
"functionTimeout": "00:10:00"
  • Click Save to lock in the changes
  • Click on the dropdown and select requirements.psd1
  • You can remove the ‘Az’ = ‘5.*’ as it won’t be used
  • Click Save to lock in the changes
  • Create a new Azure Function Functions > Add:
  • Create a new HTTP Trigger function, by selecting the options as shown below
  • Scroll down, name the function InvokePnPSiteTemplate
  • Set Authorization level, Anonymous
  • Click Save

Upload the code for your Azure Function

  • Go to the Function App main screen and select Advanced Tools
  • Click “Go”, this will open Kudu
  • Select “PowerShell” from the Debug Console menu at the top.
  • Navigate to site\wwwroot\InvokePnPSiteTemplate

This is where it gets complicated. Hold on to your hats.

Extract the AzureFunCode.zip file provided as a sample.

  • Add your PnP template into the pnp-template.xml file
  • Update run.ps1
    • set $filePath to the correct drive [C or D] that you see in the azure portal
  • set $AzAppId to match your Azure App Id
    • set $certFileName to match your exported certificate
    • set $tenant to match your tenant prefix
  • Drag & drop the files to the site\wwwroot\InvokePnPSiteTemplate directory

NOTE: If you want to use a different version of PnP PowerShell then you can generate the PnP.PowerShell files for upload from the command line. Use the folder that is exported to upload.

Create a new folder and then execute the following commands

Save-Module PnP.PowerShell . 
  1. After the code is updated. Navigate back to Function screen on Azure portal and click on ‘Get Function Url’ and copy the URL

Create the Flow

  1. Go to the Power Automate site, sign in, and choose Create -> Automated Cloud Flow
  2. Click Skip at this screen
  1. Click ‘untitled’ and give the Flow a name, PnPProvisioningDemo
  1. Search for Request, and select Request – When a HTTP Request is received.
  1. Enter the following JSON as your request body:
{
    "type": "object",
    "properties": {
        "webUrl": {
            "type": "string"
        },
        "parameters": {
            "type": "object",
            "properties": {
                "event": {
                    "type": "string"
                },
                "product": {
                    "type": "string"
                }
            }
        }
    }
}
  • Select + New Step and choose Add an action.
  • In the search box type ‘http’ and click HTTP
  • Configure the properties as shown below.
  • You also need the Azure Function, HTTP endpoint. This is in the Azure Function, Overview screen, click Get Function Url
  • Copy this http endpoint to then paste into the flow
  • Choose Save Flow. This will generate the URL that you will copy in the next step.
  • Back in the Flow, Paste the URI in this box
  • Save the Flow
  • Once save is completed, click back on the first step and copy the Flow HTTP Post Url. Save this for later

Create the Site Design

In this section we are going to create a SharePoint Site Design, based on a Team Site template.

  1. Open SharePoint Online Management Shell and connect to your tenant using Connect-SPOService
Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com
  • Update the URL property in the code below. Set the url property to the value you copied when you created the flow
{
  "$schema": "schema.json",
  "actions": [
   {
      "verb": "triggerFlow",
      "url": "{UPDATE THE FLOW URL HERE}",
      "name": "Apply PnP Template",
      "parameters": {}
    }
  ],
  "bindata": {},
  "version": 1
}
  • Select the JSON again and copy it, this will put it on your ‘clipboard
  • Open PowerShell and enter the following to copy the script into a variable and create the site script:
$script = Get-Clipboard -Raw
#before the next step verify you have data in $script by typing this
$script
#if that is empty try the copy and run the first line again.
Add-SPOSiteScript -Title "Contoso Team Config" -Content $script
Get-SPOSiteScript
  • You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created and copy it to the clipboard.
  • Use the following command to create the site design:
Add-SPOSiteDesign -Title "Contoso Team" -SiteScripts {Paste the ID of the Site Script here} -WebTemplate "64"

Conclusion

That completes all the necessary steps to get the basics up and running. Hope this was helpful walkthrough to make your first time getting started a little easier. The screens are constantly changing in Office 365 but the basics steps should remain the same. Leave a comment below if you get stuck or have a suggestion.

]]>
https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/feed/ 0 2357
Set Modern Page Properties with PnP PowerShell https://thomasdaly.net/2020/06/01/set-modern-page-properties-with-pnp-powershell/ https://thomasdaly.net/2020/06/01/set-modern-page-properties-with-pnp-powershell/#comments Mon, 01 Jun 2020 19:59:31 +0000 https://thomasdaly.net/?p=1857 Recently I had to provision a number of modern pages w/ some additional page properties. These page properties were custom fields added as columns to the Site Pages library. I found it somewhat annoying that there was not direct way to provision a page via PnP PowerShell with properties.

This blog covers the 2 steps w/ code on creating a new modern page (aka client side page) and then getting that page as a list item and updating its properties.

Step 1 of creating the page is very simple but, as you can see, you cannot supply additional values for custom properties. https://docs.microsoft.com/en-us/powershell/module/sharepoint-pnp/add-pnpclientsidepage?view=sharepoint-ps

Add-PnPClientSidePage -Name "My New Page" -PromoteAs NewsArticle -Publish

Step 2 is to find the page and then update it as a list item. In case you didn’t know, everything inside the -Values @{} are your custom properties. https://docs.microsoft.com/en-us/powershell/module/sharepoint-pnp/set-pnplistitem?view=sharepoint-ps

$page = Get-PnPListItem -List "Site Pages" -Query "<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>My New Page</Value></Eq></Where><RowLimit>1000</RowLimit></Query></View>"

Set-PnPListItem -List "Site Pages" -Identity $page.ID -Values @{"Title"="My New Page";"Classification"="News";"Article_x0020_Date"=$startDateTime.AddDays($i); "LocationTag"="Enterprise Taxonomy|Locations|$location";}

I was unable to find a command-let to just get me the page by title. This CAML query should help you out.

]]>
https://thomasdaly.net/2020/06/01/set-modern-page-properties-with-pnp-powershell/feed/ 4 1857
Renewed Office Server & Services Microsoft MVP for 2019 – 2020 https://thomasdaly.net/2019/07/03/renewed-office-server-services-microsoft-mvp-for-2019-2020/ https://thomasdaly.net/2019/07/03/renewed-office-server-services-microsoft-mvp-for-2019-2020/#comments Wed, 03 Jul 2019 00:46:49 +0000 https://thomasdaly.net/?p=1642 I’m thrilled to announce that I’ve been re-awarded my MVP for the upcoming year. This past year had some unique challenges with the birth of my 2nd little girl. She didn’t like to sleep and required much more attention that our first child. Let’s just say my time became a precious commodity. I magically managed to execute a number of local events for my NJ and NYC community, travel around the country to a number of fantastic SPS Events [San Francisco, Boston, DC, Philly] and to top it all off, squeezed in a trip to India for SPS Ahmedabad and to visit one of the SoHo Dragon offices to work with a talented group of people.

New call-to-action

I look forward to the road ahead – I already have planned a number of events where I’ll be speaking . I also have a number of local events I plan to run. I’m hoping to bring back an SharePoint Saturday NJ in the form of O365 or maybe M365 Saturday? I also plan to increase some of my online contributions… I have so many useful tips and example projects that I would love to share if I can just find more of that precious time.

]]>
https://thomasdaly.net/2019/07/03/renewed-office-server-services-microsoft-mvp-for-2019-2020/feed/ 1 1642
Update: SPFx Automatically Generating Revision Numbers + Versioning https://thomasdaly.net/2018/08/21/update-spfx-automatically-generating-revision-numbers-versioning/ https://thomasdaly.net/2018/08/21/update-spfx-automatically-generating-revision-numbers-versioning/#comments Tue, 21 Aug 2018 04:21:23 +0000 https://thomasdaly.net/?p=1611 I’ve been using the auto generated build numbers paired with Stefan Bauer: How to version new SharePoint Framework projects and it’s been working great for myself. There is however, one minor issue. After running ‘npm version major/minor/patch’ it will also run the build/bundle that automatically increments the revision numbers. This is an unwanted side effect.

Running ‘npm version major/minor/patch’ requires a clean tree, but the build/bundle modifies the package-solution.json file causing a problem. I’ve updated the build/bundle code to accept a parameter that will NOT automatically increment the revision number. Ultimately I’m fixing a problem that I caused.

Let’s take a see an example.

First thing that you need is an extra npm package called ‘gulp-util’

npm install --save-dev gulp-util

Here are the gulpfile.js enhancements again, specifically gutil & fs

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
const gutil = require('gulp-util');
const fs = require('fs');

Next add the gulp task to bump the revision. You can see that this task is looking for an argument called ‘–no-revision’. If  ‘–no-revision’ is specified in the build or bundle command it will noop on the bumpRevision task.

var getJson = function (file) {
  return JSON.parse(fs.readFileSync(file, 'utf8'));
};

let bumpRevisionSubTask = build.subTask('bump-revision-subtask', function(gulp, buildOptions, done) {
  var skipBumpRevision = buildOptions.args["revision"] === false;
  if(!skipBumpRevision) {
    var pkgSolution = getJson('./config/package-solution.json');
    var oldVersionNumber = String(pkgSolution.solution.version);
    gutil.log('Old Version: ' + oldVersionNumber);
    var oldBuildNumber = parseInt(oldVersionNumber.split('.')[3]);
    gutil.log('Old Build Number: ' + oldBuildNumber);
    var newBuildNumber = oldBuildNumber+1;
    gutil.log('New Build Number: ' + newBuildNumber);
    var newVersionNumber = oldVersionNumber.substring(0, String(oldVersionNumber).length - String(oldBuildNumber).length) + String(newBuildNumber);
    gutil.log('New Version: ' + newVersionNumber);
    pkgSolution.solution.version = newVersionNumber;
    fs.writeFile('./config/package-solution.json', JSON.stringify(pkgSolution, null, 4));
  }
  return gulp.src('./config/package-solution.json')
  .pipe(skipBumpRevision ? gutil.noop() : gulp.dest('./config'))
});

let bumpRevisionTask = build.task('bump-revision', bumpRevisionSubTask);

Lastly register the bumpRevisionTask with the build process.

build.rig.addPreBuildTask(bumpRevisionTask);

Again … all this is above the following

build.initialize(gulp);

Now in order to skip the bumpRevisionTask you can call build/bundle like this:

gulp build --ship --no-revision

gulp bundle --ship --no-revision

That’s it… add this and you will get auto incrementing revision number w/ the option to NOT increment the build number.

 

Why is that so great? Because, if you pair this with Stefan Bauer’s npm versioning post it will run when you execute the ‘npm version major/minor/patch’ command causing a version like v1.0.3.1 … instead of v1.0.3.0

 

I’ll leave you with an example of my build commands for new versions that I’m releasing to dev/staging/prod.

build-patch.cmd

cls

call gulp clean

call gulp build --ship --no-revision

call gulp bundle --ship --no-revision

call npm version patch

call gulp package-solution --ship

call explorer .\sharepoint\solution\

build-minor.cmd

cls

call gulp clean

call gulp build --ship --no-revision

call gulp bundle --ship --no-revision

call npm version minor

call gulp package-solution --ship

call explorer .\sharepoint\solution\

build-major.cmd

cls

call gulp clean

call gulp build --ship --no-revision

call gulp bundle --ship --no-revision

call npm version minor

call gulp package-solution --ship

call explorer .\sharepoint\solution\

I recommend reading some of my other posts on this subject

Original Post: SPFx Automatically Generating Revision Numbers

Simple Build Script for the SharePoint Framework

Stefan Bauer: How to version new SharePoint Framework projects

 

Enjoy! let me know how this works for you and your development teams.

]]>
https://thomasdaly.net/2018/08/21/update-spfx-automatically-generating-revision-numbers-versioning/feed/ 4 1611
I’ve been renewed for Office Servers & Services MVP for 2018 – 2019! https://thomasdaly.net/2018/08/06/ive-been-renewed-for-office-servers-services-mvp-for-2018-2019/ https://thomasdaly.net/2018/08/06/ive-been-renewed-for-office-servers-services-mvp-for-2018-2019/#respond Mon, 06 Aug 2018 13:19:31 +0000 https://thomasdaly.net/?p=1590 I’ve been renewed for Office Servers & Services MVP for 2018 – 2019!

]]>
https://thomasdaly.net/2018/08/06/ive-been-renewed-for-office-servers-services-mvp-for-2018-2019/feed/ 0 1590
New Year, New Job. 2018 Enter the Dragon https://thomasdaly.net/2018/01/03/new-year-new-job-2018-enter-the-dragon/ https://thomasdaly.net/2018/01/03/new-year-new-job-2018-enter-the-dragon/#respond Wed, 03 Jan 2018 03:30:27 +0000 https://thomasdaly.net/?p=1513 New Year, New Job. 2018 Enter the Dragon

For those of you that don’t know me, I started a new gig this year. I recently joined SoHo Dragon NYC, where I still am a Office 365 & SharePoint consultant. There was a great opportunity to join their growing team in NYC. I’ll be helping to nurture and grow their Office 365 & SharePoint practice as well be a leader and mentor for some of the junior developers.

This wasn’t entirely an easy decision to start a new job. For many years (8 exactly) I was very comfortable in my previous role as a SharePoint Developer were I sat and just developed requirements that were handed to me. I worked with tons of interesting clients and solved lots of real world problems. I worked with a growing team and some of my lifelong friends. But I stayed longer than I ever thought. I’ve always had a fire inside that demands challenge and requires a level of unpredictability (why I like consulting).

New call-to-action 

I decided that it was time to make a change. Over the past few years I’ve worked with SoHo Dragon’s CTO and owner Peter Ward on different community engagements. We would car-pool on weekend trips to SharePoint Saturday’s in Boston, Baltimore other nearby states. I’ve witnessed SoHo Dragon mature as a company during that time and I liked the direction that they are going. It wasn’t until the end of 2017 when I decided that it was time to moved on from my previous work and join them. I am looking forward to the new clients and new challenges that this year brings.

]]>
https://thomasdaly.net/2018/01/03/new-year-new-job-2018-enter-the-dragon/feed/ 0 1513
SharePoint Quick Deploy & Build Process Using Node, Gulp & SP Save – Part 1 https://thomasdaly.net/2017/12/04/sharepoint-quick-deploy-build-process-using-node-gulp-sp-save-part-1/ https://thomasdaly.net/2017/12/04/sharepoint-quick-deploy-build-process-using-node-gulp-sp-save-part-1/#comments Mon, 04 Dec 2017 02:05:17 +0000 https://thomasdaly.net/?p=1527 For the past year or so I’ve been developing and building branding assets in Visual Studio Code for my Office 365 projects. Not only just creating and building assets in VS Code but I’ve build out a custom build and deployment process using node, gulp, sp save. I’ve switched from building traditional sandboxes solutions on my SharePoint VM using the full blown Visual Studio, to developing in VS Code on my main desktop continuously build/deploy to my developer tenant. Not only does this save endless hours in the deployment process alone, but the build/testing allows me to instantly see my work with minimal delay.

You don’t have to follow my process verbatim but if you have little experience with Node and using Gulp or other plugins this article can help walk you through what I am doing and how I am using in day to day. This process is most beneficial for me in branding projects where I can quickly develop and deploy branding assets [master pages, css, javascript, page layouts, images]. I can also use this process for deployment of those assets to other environments, like staging or production. I typically use this method in tandem with other methods such as SharePoint Patterns and Practices PnP. Where I use node/gulp/spsave during development and PnP for deployment to production. PnP has higher functionality in the sense you can deploy lists/libraries, custom site columns, content types…. and the node/gulp/spsave really just builds & moves assets. The spsave modules has the ability to upload files into SharePoint with meta data, but it has limitations and I rely on PnP for the initial deployment of assets.

 

New call-to-actionIn this 4 part post I’ll cover how to get your environment setup, setting up the build scripts, using the build scripts, and lastly pairing this with SharePoint PnP. Let’s get started

Part 1 – Installing the Tools & Plugins

This first step will walk through installing all the tools and plugins that I use. If you think you already know this then feel free to jump ahead to Part 2.

Visual Studio Code

In the example I will be using Visual Studio Code, https://code.visualstudio.com/. It’s not mandatory that you use visual studio code. You can use any other web development IDE that you want. I will also be running the build scripts inside the visual studio terminal. If your IDE has a built in terminal you could use that or just use the windows command line.

Installing Node

Browse to the Node.js site and download the latest LTS version. If you have this installed already then skip ahead. What we are doing works on other versions as well.
https://nodejs.org/en/

Installing Gulp

Gulp is the task runner that we will be using to automate our build tasks. If you haven’t use Gulp before it can seem overwhelming. For part 1 all you need to know is that it’s purpose is to perform tasks. Tasks can be almost anything you can think of. For our purpose, our tasks will be copy file to SharePoint. In the next section we’ll go through creating some really basic tasks. By chaining a bunch of really simple tasks we’ll be able to increase our productivity. If you want more information you can visit: https://gulpjs.com/. Okay, so lets get started.

After you’ve install Node.js, open up a command line terminal using the either of the 2 following commands:

Start -> Run -> cmd [enter] or WindowsKey+R -> cmd [enter]

at the command line terminal we will run the following command:

npm install -g gulp

This will install gulp globally within the node.js environment. We install it globally so that our local projects can use it. Leave the command line open for the next couple of steps.

Creating a Project Folder

Before we can continue we need to setup a project folder and initialize a project. From the command line enter the following commands:

cd\
md sample-project
cd sample-project
npm init

The last command will initialize a project. You can pretty much [enter], [enter], [enter] through the file. It’s not really important at this time. This init command will ultimately create a packages.json file. This file will hold all information about the packages that we will be using in our projects.

Launch Visual Studio Code

from the command line terminal enter the following command:

code .

Inside VS Code launch the terminal with the following command:

ctrl-`

From the command line inside VS Code run the following command:

npm install gulp --save-dev

This will reinstall gulp again but locally inside our project folder. You will notice a ‘node_modules’ folder created with some new folders/files in there. You might notice a ton of files and that’s OK. Installing a package installs all the packages that are requirements as well. Lastly the –save-dev will write the dependency into the packages.json file.

Packages.json

After you ran ‘npm init’ in the first few steps it created a packages.json file. This file is used to track the project dependencies. For our purposes we are using this simply as a build tool and not as a packages manager. Npm will handle adding dependencies using –save-dev or –save. Dev dependencies are once that are required to build the project so we will be using that exclusively throughout the articles. The two other primary reasons package dependencies are being tracked in this file: 1) to keep a record of the version of the installed package 2)  when you check code in you don’t commit the node_modules, running ‘npm init’ will downloaded all the packages in the packages.json

Installing gulp-watch

Gulp has the ability to watch for file changes however it has a problem with newly added files. To fix this we are going to use gulp-watch to watch for new created files without having to stop/start gulp.

from the command line terminal enter the following commands:

npm install gulp-watch --save-dev

Installing spsave

spsave is an amazing module for node that allows us to upload files into SharePoint. That might not seem impressive but it handles all the funky stuff for us, like authentication, meta data, and various library properties [check in/out]. It does exposes an easy way for us to set our configuration and the away it goes sending your files from your desktop development environment into SharePoint Online. You can visit the website for more specific settings that what we’ll cover here. https://www.npmjs.com/package/spsave.

from the command line terminal enter the following commands:

npm install spsave --save-dev

At this point we’ve installed everything that we need in order to start configuring Gulp. In the next article we’ll walk through the steps of creating our project structure and a gulpfile.js.

Stay tuned for Part 2…

]]>
https://thomasdaly.net/2017/12/04/sharepoint-quick-deploy-build-process-using-node-gulp-sp-save-part-1/feed/ 2 1527