Category Archives: PowerShell

Updating your Node.js environment

I have used to use Windows Update and Visual Studio Extensions and Updates feature. Now the problem is that keeping your Node.js environment up-to-date is not possible using those tools.

There are couple package managers available for Windows, but there are no “native” for example PowerShell command that could be executed. I don’t like to use a tool for just single task.

Node.js

You can see Node.js version number when you start Node.Js Command Prompt

UpdateNodeJs_NodeJsVersionNumber

So far the easiest way to update your Node.js to download installer from Node.js web site from https://nodejs.org/en/download/. Note that there are two versions available LTS and Current. LTS stands for Long Term Support. Now I’m currently running the latest version of Node.js so I don’t need to update it.

UpdateNodeJs_DownloadNodeJsLTS

If you select LTS (it’s selected by default), you can see that Current version is v.4.4.7 with npm version 2.15.8.

UpdateNodeJs_DownloadNodeJsCurrent

If you select Current, you can see that Current version number has changed to v.6.3.1 with npm version 3.10.3.

Npm

If I have the latest version of Node.js, it doesn’t mean that I have the latest version of NPM. I found really excellent script that will update NPM for you with couple commands. https://www.npmjs.com/package/npm-windows-upgrade. It will show the current version of the NPM installed to your system. It also installs “any” NPM version you want so you can downgrade if the latest version would turn out to be buggy.

Open PowerShell as Administrator

UpdateNodeJs_StartPowerShell

Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force

UpdateNodeJs_PSSetExecutionPolicy

npm install --global --production npm-windows-upgrade

UpdateNodeJs_PSInstallNpmWindowsUpgrade

npm-windows-upgrade

UpdateNodeJs_PSNpmWindowsUpgrade

Now we can close PowerShell and start Node.js Command Prompt to verify that installation was successful.

npm version

UpdateNodeJs_CmdNpmVersion

Possible error messages

You can get few error message while executing npm-windows-upgrade.

The first one “Scripts cannot executed on this system.” comes if you haven’t changed execution policy.

UpdateNodeJs_ErrorScripts

The another one “NPM cannot be upgraded without administrative rights. To run PowerShell as Administrator, right-click PowerShell and select ‘Run as Administrator’.” comes if you try to execute npm-windows-upgrade with non-administrative mode.

UpdateNodeJs_ErrorRights

Install Script Generalization

If you have tried to execute scripts more than once, you have noticed that those are not practical. You need to type your user name and password quite often. It takes lot of effort if you want to use same scripts in different environments. It would mean that you need to make huge search and replace job every time you update something.

Now we will make those script more generic and with little effort you can easily use scripts in different tenants.

Configuration

Configurations script

The first thing is to create a common PowerShell Script that will contain all configurations. This file will be used by all other scripts. Now we need to make small change to one file and we can reuse same files over and over again.

Add New PowerShell Script Item ‘Configurations.ps1’ to Scripts project.

#
# Configurations.ps1
#
$Global:TenantName = “tenant”
$Global:ContentFolder = Join-Path $PSScriptRoot -ChildPath “..\Project.SharePointApp1.Web” -Resolve

# Do not change these lines
$Global:TenantRootUrl = “https://” + $Global:TenantName + “.sharepoint.com”
$Global:TenantAdminUrl = “https://” + $Global:TenantName + “-admin.sharepoint.com”
$Global:Credential = Get-SPOStoredCredential -Name $Global:TenantName -Type PSCredential

It defines following common variables for us:

  • TenantName contains the name of the tenancy.
  • TenantRootUrl contains the url to SharePoint root site of the tenant. As Microsoft has deprecated public site, we only have one root site.
  • TenantAdminUrl contains the url to SharePoint admin site. This needs to be used in some of the scripts.
  • Credential contains the credentials we are using to connect to the tenancy so that we don’t have to type them over and over again.

Credentials

Open Windows Credential Manager. The easiest way to do this is to type word credential to Windows Search. It gives you two results. Select Manage Windows Credentials.

Add a generic credential. Type your credentials. Make sure that you will type your tenant name to internet or network address field, because the script is looking for that information.

Using configuration

Common Settings

Now we have created one common configuration file and we have saved our credentials to secure place. We can start using this new way in other scripts.

Here is example script that activates our custom JavaScript files.

We can modify it a little bit. After this modification, you don’t need to enter user name and password anymore. If you want to use same scripts between development, testing and production environments you need to just change TenantName variable and everything works between different environments.

#
# ActivateScripts.ps1
#
& .\Configurations.ps1
$siteUrl = $Global:TenantRootUrl + “/sites/app1”
Connect-SPOnline -Url $siteUrl -Credentials $Global:Credential

We need to use local siteUrl variable, because PowerShell won’t allow use to concatenate two variables while calling Connect-SPOnline.

It would be possible to use parentheses to combine two varibles together. Then it would be Connect-SPOnline -Url ($Global:TenantRootUrl + “/sites/app1”) -Credentials $Global:Credential. Both ways are acceptable.

Upload files

We also had hard coded source path for the files. Now we can make that relative to script location so we can copy scripts to new computer and we don’t need to expect that it has same folder structure as our own development server.

#
# UpdateFiles.ps1
#
& .\Configurations.ps1
$siteUrl = $Global:TenantRootUrl + “/sites/app1”
Connect-SPOnline -Url $siteUrl -Credentials $Global:Credential
Add-SPOFile -Path (Join-Path $Global:ContentFolder “\Scripts\jquery-2.2.0.min.js”) -Folder “SiteAssets/Scripts/jQuery”
Add-SPOFile -Path (Join-Path $Global:ContentFolder “\Scripts\Project.js”) -Folder “SiteAssets/Scripts”

Install First Approach Explained

I have worked with SharePoint since 2005 and I have seen quite many ways of building SharePoint solutions.

Now when more and more companies are using cloud based services it’s time to make small change to development also. If you have followed at least a little bit of SharePoint scene during last few years, you have heard Microsoft talking about SharePoint Online and Apps model (currently Add-Ins, perhaps they will change that again to something new). At first it was how to build Apps with User Interface and how all developers should start building AppParts instead of WebParts. It has been now little less that three years since Richard diZerega posted an article about an app that will create new site collections to SharePoint (http://blogs.msdn.com/b/richard_dizeregas_blog/archive/2013/04/04/self-service-site-provisioning-using-apps-for-sharepoint-2013.aspx) using Client Side Object Model (CSOM). Now we can benefit from the work done by pioneers. OfficeDevPnp and OfficeDevPnp-PowerShell provide us excellent base to build on. Thank you for all who has made this possible.

Creating the first project

We will create two projects (PowerShell and Web Application) inside one solution. The idea behind this is

To be able to deploy from the first second of the project.
To be able to configure each environment identical.

Why this is important? It’s important because we are building application in development environment. Then we need to deploy same code and configurations to test environment and after acceptance test we will deploy everything to production environment. We can (re)create out development or test environment whenever we want with one script even development environment would be our O365 development tenancy.

Start Visual Studio and select PowerShell | PowerShell Script Project.
Name: MyProject.SharePointApp1.Scripts
Solution name: MyProject.SharePointApp1
Delete Script1.ps1 file.

Add New ASP.Net Web Application to the Solution.
Name: MyProject.SharePointApp1.Web
Select Empty Template
Clear selection from Host in the cloud.
After you have created a project add new folder called Content.

After you have completed all tasks your solution should be similar to this.

Add New PowerShell Script Item ‘CreateSiteCollection.ps1’ to Scripts project. You can see list of time zone id’s and web templates from my previous posts. Execute script. It will create default team site that we can use as playground for next projects.

#
# CreateSiteCollection.ps1
#
Connect-SPOnline -Url “https://tenant-admin.sharepoint.com” -UseWebLogin
New-SPOTenantSite -Title App1 -Url https://tenant.sharepoint.com/sites/app1 -Owner “admin@tenant.onmicrosoft.com” -TimeZone 59 -Lcid 1053 -Template “STS#1” -RemoveDeletedSite

Now when we can create site, we also need to delete sites when we want to erase all old configurations. Therefore, we need to create new PowerShell Script Item ‘DeleteSiteCollection.ps1’.

#
# DeleteSiteCollection.ps1
#
Connect-SPOnline -Url “https://tenant-admin.sharepoint.com” -UseWebLogin
Remove-SPOTenantSite -Url https://tenant.sharepoint.com/sites/app1 -SkipRecycleBin

Adding jQuery

We will continue working with our App1 project by adding jQuery NuGet package to Web project.

  1. Selecting Web project from Solution Explorer
  2. Select Manage NuGet Packages from context menu.
  3. Change tab to Browse
  4. Use search to find jQuery and install it.

Creating the first script

Now we have added jQuery to our project. It’s time for simple hello world demo. Create new JavaScript file ‘project.js’ to Scripts folder inside Web project.

jQuery(document).ready(function () {
alert(“Hello World!”);
});

Updating files to SharePoint

After we have installed jQuery and created project.js file we need to create new PowerShell Script ‘UpdateFiles.ps1’. We will upload jQuery with our own script to the site.

#
# UpdateFiles.ps1
#
Connect-SPOnline -Url “https://tenant.sharepoint.com/sites/app1” -UseWebLogin
Add-SPOFolder -Folder “SiteAssets” -Name “Scripts” -ErrorAction:SilentlyContinue
Add-SPOFolder -Folder “SiteAssets/Scripts” -Name “jQuery” -ErrorAction:SilentlyContinue
Add-SPOFile -Path “C:\SourceCode\MyProject.SharePointApp1\MyProject.SharePointApp1.Web\Scripts\jquery-2.2.0.min.js” -Folder “SiteAssets/Scripts/jQuery”
Add-SPOFile -Path “C:\SourceCode\MyProject.SharePointApp1\MyProject.SharePointApp1.Web\Scripts\Project.js” -Folder “SiteAssets/Scripts”

Files have been uploaded there successfully as we can see from the following image, but the problem is that we didn’t get the message. We still need to add those scripts to the page so that we can execute them in user’s browser.

Adding scripts to the site

Adding custom scripts to site can be done using Add-SPOCustomAction. The problem is that you can’t define script source even it has parameter called Url. At first we need to create custom action and then we need to update ScriptSrc property. Now you can see “Hello World!” text on you site.

#
# ActivateScripts.ps1
#
Connect-SPOnline -Url “https://tenant.sharepoint.com/sites/app1” -UseWebLogin
Add-SPOCustomAction -Description “jQuery” -Location “ScriptLink” -Name “jQuery” -Title “jQuery” -Group “Project” -Sequence 10050 -Scope “Site”
$action = Get-SPOCustomAction -Scope “Site” | ? { $_.Description -eq “jQuery” }
$action.ScriptSrc = “~sitecollection/SiteAssets/Scripts/jQuery/jquery-2.2.0.min.js”
$action.Update()
Execute-SPOQuery

Add-SPOCustomAction -Description “ProjectScript” -Location “ScriptLink” -Name “ProjectScript” -Title “ProjectScript” -Group “Project” -Sequence 10051 -Scope “Site”
$action = Get-SPOCustomAction -Scope “Site” | ? { $_.Description -eq “ProjectScript” }
$action.ScriptSrc = “~sitecollection/SiteAssets/Scripts/Project.js”
$action.Update()
Execute-SPOQuery

Now we have simple template that allows us to update scripts and sites with scripts. If we need to set up new environment, all we need to do is to execute those scripts and environment is ready for action.

SharePoint Online Templates

Here is a list of SharePoint Online web templates. These are needed if you want to create a new site collection.

#
# ListWebTemplates.ps1
#
Connect-SPOnline -Url “https://tenant-admin.sharepoint.com” -UseWebLogin
Get-SPOWebTemplates -Lcid 1033
Name Title Category Compatiblity Level
STS#0 Team Site Collaboration 15
BLOG#0 Blog Collaboration 15
BDR#0 Document Center Enterprise 15
DEV#0 Developer Site Collaboration 15
OFFILE#1 Records Center Enterprise 15
EHS#1 Team Site – SharePoint Online configuration Enterprise 15
BICenterSite#0 Business Intelligence Center Enterprise 15
SRCHCEN#0 Enterprise Search Center Enterprise 15
BLANKINTERNETCONTAINER#0 Publishing Portal Publishing 15
ENTERWIKI#0 Enterprise Wiki Publishing 15
PROJECTSITE#0 Project Site Collaboration 15
PRODUCTCATALOG#0 Product Catalog Publishing 15
COMMUNITY#0 Community Site Collaboration 15
COMMUNITYPORTAL#0 Community Portal Enterprise 15
SRCHCENTERLITE#0 Basic Search Center Enterprise 15
visprus#0 Visio Process Repository Enterprise 15

SharePoint Time Zones

Here is a list of SharePoint Online time zone id’s. These are needed if you want to create a new site collection.

#
# ListTimeZones.ps1
#
Connect-SPOnline -Url “https://tenant.sharepoint.com” -UseWebLogin
Get-SPOTimeZoneId
Id Description Identifier
0 None No:ne
2 GREENWICH MEAN TIME DUBLIN EDINBURGH LISBON LONDON UTC
3 BRUSSELS COPENHAGEN MADRID PARIS UTC+01:00
4 AMSTERDAM BERLIN BERN ROME STOCKHOLM VIENNA UTC+01:00
5 ATHENS BUCHAREST ISTANBUL UTC+02:00
6 BELGRADE BRATISLAVA BUDAPEST LJUBLJANA PRAGUE UTC+01:00
7 MINSK UTC+02:00
8 BRASILIA UTC-03:00
9 ATLANTIC TIME CANADA UTC-04:00
10 EASTERN TIME US AND CANADA UTC-05:00
11 CENTRAL TIME US AND CANADA UTC-06:00
12 MOUNTAIN TIME US AND CANADA UTC-07:00
13 PACIFIC TIME US AND CANADA UTC-08:00
14 ALASKA UTC-09:00
15 HAWAII UTC-10:00
16 MIDWAY ISLAND SAMOA UTC-11:00
17 AUKLAND WELLINGTON UTC+12:00
18 BRISBANE UTC+10:00
19 ADELAIDE UTC+09:30
20 OSAKA SAPPORO TOKYO UTC+09:00
21 KUALA LUMPUR SINGAPORE UTC+08:00
22 BANGKOK HANOI JAKARTA UTC+07:00
23 CHENNAI KOLKATA MUMBAI NEW DELHI UTC+05:30
24 ABU DHABI MUSCAT UTC+04:00
25 TEHRAN UTC+03:30
26 BAGHDAD UTC+03:00
27 JERUSALEM UTC+02:00
28 NEWFOUNDLAND AND LABRADOR UTC-03:30
29 AZORES UTC-01:00
30 MID ATLANTIC UTC-02:00
31 MONROVIA UTC
32 CAYENNE UTC-03:00
33 GEORGETOWN LA PAZ SAN JUAN UTC-04:00
34 INDIANA EAST UTC-05:00
35 BOGOTA LIMA QUITO UTC-05:00
36 SASKATCHEWAN UTC-06:00
37 GUADALAJARA MEXICO CITY MONTERREY UTC-06:00
38 ARIZONA UTC-07:00
39 INTERNATIONAL DATE LINE WEST UTC-12:00
40 FIJI ISLANDS MARSHALL ISLANDS UTC+12:00
41 MADAGAN SOLOMON ISLANDS NEW CALENDONIA UTC+11:00
42 HOBART UTC+10:00
43 GUAM PORT MORESBY UTC+10:00
44 DARWIN UTC+09:30
45 BEIJING CHONGQING HONG KONG SAR URUMQI UTC+08:00
46 NOVOSIBIRSK UTC+06:00
47 TASHKENT UTC+05:00
48 KABUL UTC+04:30
49 CAIRO UTC+02:00
50 HARARE PRETORIA UTC+02:00
51 MOSCOW STPETERSBURG VOLGOGRAD UTC+03:00
53 CAPE VERDE ISLANDS UTC-01:00
54 BAKU UTC+04:00
55 CENTRAL AMERICA UTC-06:00
56 NAIROBI UTC+03:00
57 SARAJEVO SKOPJE WARSAW ZAGREB UTC+01:00
58 EKATERINBURG UTC+05:00
59 HELSINKI KYIV RIGA SOFIA TALLINN VILNIUS UTC+02:00
60 GREENLAND UTC-03:00
61 YANGON RANGOON UTC+06:30
62 KATHMANDU UTC+05:45
63 IRKUTSK UTC+08:00
64 KRASNOYARSK UTC+07:00
65 SANTIAGO UTC-04:00
66 SRI JAYAWARDENEPURA UTC+05:30
67 NUKU ALOFA UTC+13:00
68 VLADIVOSTOK UTC+10:00
69 WEST CENTRAL AFRICA UTC+01:00
70 YAKUTSK UTC+09:00
71 ASTANA DHAKA UTC+06:00
72 SEOUL UTC+09:00
73 PERTH UTC+08:00
74 KUWAIT RIYADH UTC+03:00
75 TAIPEI UTC+08:00
76 CANBERRA MELBOURNE SYDNEY UTC+10:00
77 CHIHUAHUA LA PAZ MAZATLAN UTC-07:00
78 TIJUANA BAJA CALFORNIA UTC-08:00
79 AMMAN UTC+02:00
80 BEIRUT UTC+02:00
81 MANAUS UTC-04:00
82 TBILISI UTC+04:00
83 WINDHOEK UTC+02:00
84 YEREVAN UTC+04:00
85 BUENOS AIRES UTC-03:00
86 CASABLANCA UTC
87 ISLAMABAD KARACHI UTC+05:00
88 CARACAS UTC-04:30
89 PORT LOUIS UTC+04:00
90 MONTEVIDEO UTC-03:00
91 ASUNCION UTC-04:00
92 PETROPAVLOVSK KACHATSKY UTC+12:00
93 COORDINATED UNIVERSAL TIME UTC
94 ULAANBAATAR UTC-08:00