Tuesday, September 4, 2018

Renaming a SharePoint 2010/2013 Server

Copyright from: www.cdh.com

Have you ever found yourself in the situation where you wished you had named your SharePoint server differently? Renaming that server isn’t exactly straight forward. You can’t simply rename the machine and call it good. SharePoint contains many references to the name of your machine throughout it’s database, and all of these must be changed as well. Luckily, Microsoft has provided us with a handy PowerShell cmdlet called Rename-SPServer to make most of these changes. There’s more to it than just this command, however, so I’m going to go through all of the steps that I have a lot of success with.
In a nutshell, we’re going to first rename the server in SharePoint’s eyes using PowerShell, then actually rename the machine itself, fix a few things neither of those two steps updated for us, and run an upgrade command. And we should be doing all of this as the Farm Account to ensure we don’t run into any permission issues performing these steps.
If this is a 2013 server, we’re also going to have to contend with the Distributed Cache service. The first time I tried to rename a 2013 server I had a bear of a time with this service still having references to the old server name and not working properly. There is a specific order these steps have to go in, otherwise you can end up with trouble.
In detail, here are the steps that I take:
1. Log into the server as the Farm Account.
2. Open SharePoint Management Shell (PowerShell).
3. If this is SharePoint 2013, execute the command:
Remove-SPDistributedCacheServiceInstance
We need to remove this before the server is renamed. Doing this out of order I was running into many difficulties getting this service working again, and getting it to forget the old name of the server.
4. Next, execute the command:
Rename-SPServer -Identity “[old_server_name_here]” -Name “[new_server_name_here]“
You will probably see an “Object not set to an instance of an object” error message, this is normal, the farm was renamed.
5. Now rename the actual Windows server itself to the same name you gave the Rename-SPServer command. These must match, otherwise you’re going to end up with SharePoint Management Shell windows that say nothing but “Farm not found”.
6. Reboot the server.
7. Log back in as the Farm Account and open the SharePoint Management Shell(PowerShell) back up again.
8. Execute the command:
New-SPAlternateURL -WebApplication http://[old_server_name]:[central_admin_port]
-Url http://[new_server_name]:[central_admin_port] -Zone Default
The Rename-SPServer cmdlet doesn’t rename the alternate access mapping for Central admin for you… it doesn’t touch any of the alternate access mappings. You’ll need to repeat this command for every Web Application you may have that is simply the old servers name on different ports.
9. Now open up a regular ole’ command prompt and execute the following:
psconfig.exe -cmd upgrade -inplace b2b -wait -force
This will take a while. You also may get an error saying the User Profile Synchronization service failed to start, which is fine. You’ll need to go start that manually via Central Admin afterwards.
10. If this is a SharePoint 2013 server, let’s head back to SharePoint Management Shell and resurrect the Distributed Cache Service by executing the command:
Add-SPDistributedCacheServiceInstance 
Now let’s head to Central admin to fix a few things there.
11. Investigate the User Profile Synchronization Service. It was most likely stopped by the upgrade above and will need to be started again. I have ran into a rare instance where it reported that it was Started, but ended up finding that it actually wasn’t provisioned. If you find this to be the case, just go to the service and see that it is running normally. Kick off an incremental to make sure. Stop and Start the service again if you run into any issues.
12. Finally, let’s head to the Search Service Application to update the Content Sources and any Crawl Rules you may have. If you have any sources or rules that reference the name of the old server, these too will need to be updated with the new server name.
After all of this you may also want refresh your Health Analyzer list, the one that drives that little yellow or red bar across the top of Central Admin telling you that it has detected some issues. If you don’t have one of these displayed, AWESOME! It’s rare to find a farm that doesn’t have something in there. If you have any issues in there they’ll most likely be reporting these issues had occurred on the old server name. Once the rule runs again later on it’ll start saying the issue exists on both the old and new server names. It doesn’t hurt anything to leave it like this, but I like to go through and clean out that entire list and let it start fresh again with the new server name.
If you don’t want to wait for all of those rules to run again over time, you can force them all on the spot with the following command in the SharePoint Management Shell:
Get-SPTimerJob | where {$_.Title -like “Health Analysis Job*”} | Start-SPTimerJob 

Monday, August 20, 2018

Solve the SharePoint Framework + Angular Challenge with Angular 5.0 Elements

Copyright from: http://www.andrewconnell.com

A few weeks ago I published a blog post on What's up with Angular (v2.x / v4.x) and the SharePoint Framework. In that post I explained what is widely accepted as the challenge to using Angular within SPFx solutions: Angular wants to have a single root component on that page that loads all other components. This presents a few challenges, leading to my recommendation to avoid Angular + SPFx for now, but not for long.
Last week at the European SharePoint Conference 2017 (ESPC) in Dublin, Ireland, Rob Wormald presented on a new tech being added to the core of Angular that I think will make Angular much more approachable and useful to so many developers. Unfortunately, this session wasn't recorded nor did I have the opportunity to attend due to co-chairing another conference in Orlando at the same time. I am familiar with the topic though as I've been assisting the Angular team in understanding SharePoint & the SharePoint Framework (SPFx) over the last few months. Over that time, I've become sold on this approach, not just for SPFx, but for Angular as a whole!

Angular Elements

This new tech I refer to above is called Angular Elements. It is part of Angular Labs, sort of like the R & D spot in the Angular team where ideas are explored & nurtured. Angular Elements will allow you to extend the reach of Angular applications by packaging them as custom elements. These custom elements are just part of the web component specification that has been implemented in some way by all the major browser vendors.
What's the benefit to Angular Elements? Well, unlike an Angular application, for lack of a better term, it's self-bootstrapping meaning it doesn't need to belong to a root component on the page.
In addition, Angular Elements will serve as the bus between the custom element and the DOM to handle inputs & outputs (attributes) as well as events as they happen within the component. It also makes zones.js optional... another thing that we had to add to every SharePoint page in order to use Angular.
One of the most important aspects of Angular Elements is that once the Angular component is compiled, the deliverable artifact is just plain old JavaScript with no external dependencies to the page... including Angular!

LET THAT SINK IN FOR A MOMENT...

You can use Angular 5.0 & Angular Elements to build your component as a custom element, then take the resulting JavaScript to another website to register your custom element and use it on the page without referencing Angular or any other framework!
In effect, I can build something with Angular Elements, give you a JS file and you can add a new element to a page for use... like this:
<html>
<head>
<script src="microsoft-cloud-show.js"></script>
<script>
// the following is defined in the above *.js file
// class MsCloudShow extends HTMLElement {}
window.customElements.define('ms-cloudshow', MsCloudShow);
</script>
</head>
<body>
<ms-cloudshow show-episode="200"></ms-cloudshow>
</body>
</html>
Take note of lines 3, 7 & 12... that's it!
More Details Angular Elements
Rob has been talking about this new tech, Angular Elements, a few times recently... if you want to learn more about Angular Elements, I suggest you check out these two videos from recent presentations. While they don't address SharePoint specifically, they do a good job of explaining the value proposition.

Web Components

How does this app happen? Angular Elements is leveraging one of the four APIs that is collectively referred to as Web Components. Specifically, it leverages the Custom Elements API which allows us to define new types of DOM elements.
They aren't all that new... in fact if you've heard of the project Polymer, that's a library for creating web components.
What's great is all browsers support web components...
... well... almost all of them fully support web components...
The browsers have different levels of support for web components and each of the different APIs. Chrome & Opera have the best support, followed by Safari. Firefox is actively developing support for custom elements & shadow DOM.
Microsoft's Edge on the other hand is still listed as "considering" support even though this feature has over 10,000 votes, while there is at least a polyfill for the time being...
More Details Web Components
Want to learn more about web components and custom components? Check out the official docs from Google & Mozilla:
Furthermore, the concept of custom components came up during the Chrome Dev Summit recently and Rob had a great take that's worth listening to: Chrome Dev Summit 2017.

Angular Elements & SharePoint Framework

So how does this impact us in the SPFx space? Using Angular Elements, you can build a component that can be used within a client-side web part or other SPFx component.
What does it look like? You can check out a sample repo of this in action... just remember this is still a work in progress: SharePoint/sp-dev-fx-angular.
Let's look at this project together. I'm going to skip some boilerplate stuff that's required to get it working within an SPFx project... I just want you to understand what you are looking at.

CREATE THE ANGULAR COMPONENT

First, create the Angular component like you normally would with Angular today. Within webparts/ngHelloWorld/elements/hello-world.ts you will find a simple component that has a single property name you can assign a value to (which is shown in the view webparts/ngHelloWorld/elements/hello-world.html):
import { Component, NgModule, Input, ViewEncapsulation } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { CommonModule } from '@angular/common';
@Component({
selector: 'hello-world',
templateUrl: `./hello-world.html`,
styleUrls: [ './hello-world.scss' ],
host: {
class: 'hello-world'
},
encapsulation: ViewEncapsulation.None
})
export class HelloWorld {
@Input() name = 'Angular'
}
@NgModule({
imports: [BrowserModule],
declarations: [HelloWorld],
entryComponents: [HelloWorld]
})
export class HelloWorldModule {
ngDoBootstrap(){}
}
view rawhello-world.ts hosted with ❤ by GitHub
Then, using Angular Elements, register the component as a custom element, as shown on line 9 in webparts/ngHelloWorld/elements/index.ts:
//web components ES5 shim
import '../../../elements/wc-shim'
import { registerAsCustomElements } from '@angular/elements';
import { platformBrowser } from '@angular/platform-browser'
import { HelloWorld, HelloWorldModule } from './hello-world'
import { HelloWorldModuleNgFactory } from './hello-world.ngfactory'
registerAsCustomElements([HelloWorld], () => platformBrowser().bootstrapModuleFactory(HelloWorldModuleNgFactory, {ngZone: 'noop'}))
.catch(err => console.log(err));
view rawindex.ts hosted with ❤ by GitHub
Finally, import it into your client-side web part and add the element to the web part's DOM element as shown in lines 11-13 in webparts/ngHelloWorld/NgHelloWorldWebPart.ts:
import './elements'
import { HelloWorld } from './elements/hello-world'
import {
BaseClientSideWebPart, IPropertyPaneConfiguration, PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
export default class NgHelloWorldWebPartWebPart extends BaseClientSideWebPart<HelloWorld> {
constructor(){ super(); }
ngElement: HTMLElement;
public render(): void {
this.domElement.innerHTML = `this.properties.name}">
`; } protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [{ header: { description: 'Description' }, groups: [ { groupName: "Options", groupFields: [ PropertyPaneTextField('name', { label: "Username", value: "Rob" }) ]}]}]}; } }
That's it! Pretty clean huh?
Better yet, you can take the same Angular Element and drop it on a page that has no web framework or one that uses Vue.js, React or jQuery using the syntax I showed above and it works the same way!
What do you think? Drop a mention in the comments below!

Awesome! Now What?

Now we wait... this isn't ready for prime time. There is still a lot to get worked out, but the POC is there. From what I understand we're just a few months away... maybe less.
Stay tuned... the story is shaping up quite nicely!
Oh... and for those of you who have subscribed to my Mastering the SharePoint Framework course, rest assured... this WILL be covered in a chapter once it's final as this is likely to be my preferred way of doing SPFx development!