tag:blogger.com,1999:blog-43571407564962469102024-03-06T01:45:53.200+01:00Azure & CoArchitectures and Development approaches regarding Azure, 0ffice 365 and SharePoint on prem, Online,
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.comBlogger84125tag:blogger.com,1999:blog-4357140756496246910.post-39455458676765677042023-09-17T12:09:00.004+02:002023-09-20T12:19:30.619+02:00call an Azure Active Directory protected API from an Angular 16 SPA using MSAL V2<h2>Overwiev</h2>
This post is an upgrade of the <a href="https://pshul.com/2020/02/07/azure-ad-authentication-from-angular-to-azure-functions/">great post of Alex Pshul on the same topic</a>.
<br />This helped me a lot, thanks to him!
<br />I had to ugrade Alex's port and source code because:
<ul>
<li>The <a target='blank' href="https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-acquire-token?tabs=angular2">new MS doc for MSAL V2 ( @azure/msal-angular V3 )</a> shows new code for configuration in app.module.ts</li>
<li>The way on configuring AAD apps in Azure Portal has changed too</li>
<li>Last, I couldn't complie with Angular 16 Alex's code and other codes found that were all written at leaast 2 years ago.
<br>No post on this topic found for 2 years</li>
</ul>
If you are not familiar with MSAL and authentication flow for SPA and Azure API, you should first <a target='blank' href="https://mosshowto.blogspot.com/2023/09/spa-api-azure-ad-msal-js.html">read my previous post that is detailling all that</a> and presents a simple JavaScript solution that allows you to test your Azure configuration.
<br />
Regarding angular 16 SPA, Azure API and MSAL V2, steps are the following:
<h2>Azure config and Angular code for SPA authentication</h2>
Create an AAD app for your Angular SPA with a redirect url set to http://localhost:4200
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggqyFe573_3P0-5xmy5AHr2-rriClU8sPOgE19GLbjS6M9aKuwMJWq8Phww1YcdA_umF6QxW-42dQ-Ej35gmy-P6dCvu7jGQSTQhXdfPY8x7tgi8y_K2EpZRv3grp3WtHYK5frzgN9kqPHvm1o8fv8ydrKVyv0I5GqkC6ukDy5Tyo3p3GRul9woyUuM7zz/s1600/ScreenAzure-AD-SPA-API-MSAL-05-SPA%20app%20registration.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" style="width:50%" data-original-height="867" data-original-width="1593" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggqyFe573_3P0-5xmy5AHr2-rriClU8sPOgE19GLbjS6M9aKuwMJWq8Phww1YcdA_umF6QxW-42dQ-Ej35gmy-P6dCvu7jGQSTQhXdfPY8x7tgi8y_K2EpZRv3grp3WtHYK5frzgN9kqPHvm1o8fv8ydrKVyv0I5GqkC6ukDy5Tyo3p3GRul9woyUuM7zz/s1600/ScreenAzure-AD-SPA-API-MSAL-05-SPA%20app%20registration.png"/></a></div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSkyPGvfcYEeAmIXzZT0wsxNSh9N3e582KJs_2xPqaJccdsmAJi1OzTbDp2BJsJqLNJvzwxkTZL3IUoCtYzaLoaQQgsIjKJ5WvdCarjBoFIQjOs_uJgBfS-adL3LjLxjjmi0PaqI9TAkWIcZ86QS9yvijbmilPGpMpHQoc_nLBwSGL8oXmrnvvUu58kUS0/s1600/Azure-AD-Angular-SPA-API-MSAL-03-SPA%20AAD%20App%20created.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="900" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSkyPGvfcYEeAmIXzZT0wsxNSh9N3e582KJs_2xPqaJccdsmAJi1OzTbDp2BJsJqLNJvzwxkTZL3IUoCtYzaLoaQQgsIjKJ5WvdCarjBoFIQjOs_uJgBfS-adL3LjLxjjmi0PaqI9TAkWIcZ86QS9yvijbmilPGpMpHQoc_nLBwSGL8oXmrnvvUu58kUS0/s1600/Azure-AD-Angular-SPA-API-MSAL-03-SPA%20AAD%20App%20created.png"/></a></div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxu2O4W4fd9rw_txDh8MXxiRJmtmadCDYzjud6vKD5aX3B7L_kCtWnSzqJI6B2FrT-8qGOCJ4DoMUfr4avW6kgZbG8DTQIH9OLrN59d4g-900tvxDvqVZCGvs9lwfU9c5VJzLIHQQDebN9XiRFqZIfKbiSbeHKm69Dr2Gd3iyeJd_flj37gmRf8JM0RTBU/s1600/Azure-AD-Angular-SPA-API-MSAL-04-SPA%20AAD%20App%20overview.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="816" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxu2O4W4fd9rw_txDh8MXxiRJmtmadCDYzjud6vKD5aX3B7L_kCtWnSzqJI6B2FrT-8qGOCJ4DoMUfr4avW6kgZbG8DTQIH9OLrN59d4g-900tvxDvqVZCGvs9lwfU9c5VJzLIHQQDebN9XiRFqZIfKbiSbeHKm69Dr2Gd3iyeJd_flj37gmRf8JM0RTBU/s1600/Azure-AD-Angular-SPA-API-MSAL-04-SPA%20AAD%20App%20overview.png"/></a></div>
Copy the AAD app client ID and your tenant id
<br />
Update your @NgModule app.module.ts with this code while replacing the client id and tenaant id by your own values:
<pre>
@NgModule({
declarations: [AppComponent, HomeComponent, ProfileComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
MatButtonModule,
MatToolbarModule,
MatListModule,
HttpClientModule,
MsalModule.forRoot(
// MSAL Configuration V2. Mandatory! V1 outside NgModule no longer works
new PublicClientApplication({
auth: {
clientId: "9fefb62c-5e82-4a09-acc3-ea077f8164f3", // Application (client) ID from the app registration
authority:
"https://login.microsoftonline.com/994d9022-89d7-44f4-91e2-3851290dc50d", // The Azure cloud instance and the app's sign-in audience (tenant ID, common, organizations, or consumers)
redirectUri: "http://localhost:4200/", // This is your redirect URI,
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: isIE,
},
}),
//MSAL Guard V2.
null,
null,
),
],
providers:
[],
bootstrap: [AppComponent, MsalRedirectComponent],
})
export class AppModule { }
</pre>
<a target='blank' href="https://github.com/MarcCharmois/Angular-V16-MSAL-V3-SPA-API-CALL"><div style="height:20px; width:150px; background-color:#99b3ff;color:white;border-radius:5px; padding:5px;">Get the code</div></a>
I let this post id values in the code to help you.
<br>
<b>Microsoft doc on the topic can also help</b>: <a target='blank' href="https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-sign-in?tabs=angular2">SPA that signs in users and calls a Web API</a>
<br>
<br>
Normally, if you configured well, you should be able to sign in with AAD to your Angular SPA:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn-L7_lZo57IuEeta-YFT7LsktFEyWxGJ_g-_r2uaMjBPgrOPFpaCQTv8sQ-KLNYia4dQgk_f8Qo4RLn5Kj467Ivu2NMxxcCx9Y4MeUBwOmTKPMSncOQzrRzuAWJDdshJM7fA3faMqGJruB9IDmheZd17aaN73yqwAPkCZqbPk40UeqJQJVFRU76eW5QW4/s1600/Azure-AD-Angular-SPA-API-MSAL-05-SPA%20first%20sign%20in%20with%20AAD.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn-L7_lZo57IuEeta-YFT7LsktFEyWxGJ_g-_r2uaMjBPgrOPFpaCQTv8sQ-KLNYia4dQgk_f8Qo4RLn5Kj467Ivu2NMxxcCx9Y4MeUBwOmTKPMSncOQzrRzuAWJDdshJM7fA3faMqGJruB9IDmheZd17aaN73yqwAPkCZqbPk40UeqJQJVFRU76eW5QW4/s1600/Azure-AD-Angular-SPA-API-MSAL-05-SPA%20first%20sign%20in%20with%20AAD.png"/></a></div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbAIaOp4wqjMfKT0i-irzT6IyliG397PsWvtwne7BYIWA5qZbst6-z9TVYQL7vO_E-vNW1x8U_4yVnPYUv1ydhBHnknRVZriQsIlAbAKwYTTHtsRiz83L7Ms3GBygfIX9RbEori4O7mIegzlITvWs9MnE7x6gh4flmn47NTHnnAhxhPuOMEYyDhIa-gUMY/s1600/Azure-AD-Angular-SPA-API-MSAL-06-SPA%20first%20successful%20sign%20in%20with%20AAD.png.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbAIaOp4wqjMfKT0i-irzT6IyliG397PsWvtwne7BYIWA5qZbst6-z9TVYQL7vO_E-vNW1x8U_4yVnPYUv1ydhBHnknRVZriQsIlAbAKwYTTHtsRiz83L7Ms3GBygfIX9RbEori4O7mIegzlITvWs9MnE7x6gh4flmn47NTHnnAhxhPuOMEYyDhIa-gUMY/s1600/Azure-AD-Angular-SPA-API-MSAL-06-SPA%20first%20successful%20sign%20in%20with%20AAD.png.png"/></a></div>
<h2>Azure config and Angular code for API authentication (SSO)</h2>
If you don't have any API for testing you can quickly get one by following the steps described in <a target='blank' href="https://mosshowto.blogspot.com/2023/09/get-quickly-azure-api-powershell.html">this previous post</a>
<br>
From the API configuuration in Azure portal click authentication in the left menu. Then click "add identity provider"
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9aug4kHSPa5-aYdiHtpoXHXp8W6TDwY0No65TW_9EsE1o0dIoTnHF2nwA-BI-qxDNRIPRWKh1WgQQ0Mx73uEiGLqpRBcfS5qgPUIkCVJKqeG5GoMbfIp0yrEpQ_YCUmsM13JY3xEsDJYYplbYoUDzure-kZwOvZ2A_U9nhgGeFy4JXauDdz6bpiGFpBUj/s1600/Azure-AD-Angular-SPA-API-MSAL-07-adding%20identity%20provider%20to%20the%20API.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9aug4kHSPa5-aYdiHtpoXHXp8W6TDwY0No65TW_9EsE1o0dIoTnHF2nwA-BI-qxDNRIPRWKh1WgQQ0Mx73uEiGLqpRBcfS5qgPUIkCVJKqeG5GoMbfIp0yrEpQ_YCUmsM13JY3xEsDJYYplbYoUDzure-kZwOvZ2A_U9nhgGeFy4JXauDdz6bpiGFpBUj/s1600/Azure-AD-Angular-SPA-API-MSAL-07-adding%20identity%20provider%20to%20the%20API.png"/></a></div>
Choose Microsoft as provider, give a name to the AAD app.
<br>It is better to create new app for an api, because, doing this way, Azure will configure your app service to be called and to allow user authentication without problem.
<br>If you choose an existing AAD app, you may have other configurtaions, not done by Azure, to perform yourself at the app service level (json config, web config, etc.)
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg70lWmAHYwqZXhhy2SwWtOptCtdj_tkjzfMbktEI7DSfX0Bnn5jQfsTZvuCfogGpWXJnwVbjVT5p-8EJg4950Q-u-014XWtDCwrV54ZVvZFhmJiuvXiCGe2viPznveeBcQesU6cxbYoKWZzNBKpH3-BsE4a653SWFAb5nXDTKQqhO-Ikto2wQNXjHqLHmB/s1600/Azure-AD-Angular-SPA-API-MSAL-08-defining%20identity%20provider%20for%20the%20API.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg70lWmAHYwqZXhhy2SwWtOptCtdj_tkjzfMbktEI7DSfX0Bnn5jQfsTZvuCfogGpWXJnwVbjVT5p-8EJg4950Q-u-014XWtDCwrV54ZVvZFhmJiuvXiCGe2viPznveeBcQesU6cxbYoKWZzNBKpH3-BsE4a653SWFAb5nXDTKQqhO-Ikto2wQNXjHqLHmB/s1600/Azure-AD-Angular-SPA-API-MSAL-08-defining%20identity%20provider%20for%20the%20API.png"/></a></div>
This is the screenshot of the finalized API identity provider
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglM_NAzLDDh9PO-EFlB0uoUSxT901Dn3dJAM_CSROAkRz_rGl-mBUwecPSOfnNyP8D3WzMuk_jvsn3Q3yspoBHA8hukVDB_QhV12flhknBTcaUBmcD5zg0swRiaAYci2X9lkJUwKuIs1zTyVOFqqSmWttyulDy_bpMi6npqHdPRfQJP5yjeuev2JrIlVGu/s1600/Azure-AD-Angular-SPA-API-MSAL-09-%20iidentity%20provider%20for%20the%20API%20created.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglM_NAzLDDh9PO-EFlB0uoUSxT901Dn3dJAM_CSROAkRz_rGl-mBUwecPSOfnNyP8D3WzMuk_jvsn3Q3yspoBHA8hukVDB_QhV12flhknBTcaUBmcD5zg0swRiaAYci2X9lkJUwKuIs1zTyVOFqqSmWttyulDy_bpMi6npqHdPRfQJP5yjeuev2JrIlVGu/s1600/Azure-AD-Angular-SPA-API-MSAL-09-%20iidentity%20provider%20for%20the%20API%20created.png"/></a></div>
If you click the link of the app name you will be redirected to the app in Azure Active Directory.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwy8yuL_GoevDdeM1P_IQb9FPKJNFcBnUPlLed4BKu1q86JJiBvwc6AbpB2I69Ddu59CQnFNhBdloKl_Fsmde8S8vnl9e7lfCvLlYTsX6hvbgWNCJUxsnwfFFsxoBPblQz9GWvLNA4eY55G9agR4jBRS2-DShHA6888vuj7sKJ6GNm_uOBFErlpFtzMm2E/s1600/Azure-AD-Angular-SPA-API-MSAL-10-overview%20of%20the%20API%20app%20in%20azure%20active%20directory.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwy8yuL_GoevDdeM1P_IQb9FPKJNFcBnUPlLed4BKu1q86JJiBvwc6AbpB2I69Ddu59CQnFNhBdloKl_Fsmde8S8vnl9e7lfCvLlYTsX6hvbgWNCJUxsnwfFFsxoBPblQz9GWvLNA4eY55G9agR4jBRS2-DShHA6888vuj7sKJ6GNm_uOBFErlpFtzMm2E/s1600/Azure-AD-Angular-SPA-API-MSAL-10-overview%20of%20the%20API%20app%20in%20azure%20active%20directory.png"/></a></div>
We are now going to let this API app authorize access to user authenticated from the SPA.
<br>
So click "expose an API" from the left menu, and in the "Expose an API" pane, click "add a client application"
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTfVAHIVMcnWrV-VSG1M_4_Kpg8traBxP1LE1OcTK6FqA8lWNNXWPIqfAkuZB5Kt3_XmIc0ozWhUrCpUqaZSbKAEJ0ehb6yUr96dbbunDD8-AcqZlBP-INzWGeEeE6yhxo1RP-Axav8Ot0RQaPcOhf8J8YvWJy7r320wFI7lu9UUvIuArBl7Koaaxlzro7/s1600/Azure-AD-Angular-SPA-API-MSAL-11-ading%20a%20client%20application%20to%20API%20app.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="860" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTfVAHIVMcnWrV-VSG1M_4_Kpg8traBxP1LE1OcTK6FqA8lWNNXWPIqfAkuZB5Kt3_XmIc0ozWhUrCpUqaZSbKAEJ0ehb6yUr96dbbunDD8-AcqZlBP-INzWGeEeE6yhxo1RP-Axav8Ot0RQaPcOhf8J8YvWJy7r320wFI7lu9UUvIuArBl7Koaaxlzro7/s1600/Azure-AD-Angular-SPA-API-MSAL-11-ading%20a%20client%20application%20to%20API%20app.png"/></a></div>
Fill the client id fiield with the client id of the SPA AAD app you previously put in your angular code.
<br>
check the scope checkbox that is a delagated permission for users authenticated with the SPA to access the API without needing to sign in again (SSO).
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVh49GFZNJyg6cZX_TIX5SZk_B7UW8AjesgUJGu3AhIviU7GZ5N0W2fm-vTAs_uaHozmbnaD2Yr-GCX0sxMiQXMSoh8xylF3cmkTII0_ktt_Hbr1kbvw8xtXh1D6pZy63ncEvEMksYr1cvGFjszgnit0mHeckDJ_iBb6xdAQj9VCjdR2_21GuPEYyutTnk/s1600/Azure-AD-Angular-SPA-API-MSAL-12-ading%20a%20client%20application%20to%20API%20app%20-%20spa%20client%20id.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="855" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVh49GFZNJyg6cZX_TIX5SZk_B7UW8AjesgUJGu3AhIviU7GZ5N0W2fm-vTAs_uaHozmbnaD2Yr-GCX0sxMiQXMSoh8xylF3cmkTII0_ktt_Hbr1kbvw8xtXh1D6pZy63ncEvEMksYr1cvGFjszgnit0mHeckDJ_iBb6xdAQj9VCjdR2_21GuPEYyutTnk/s1600/Azure-AD-Angular-SPA-API-MSAL-12-ading%20a%20client%20application%20to%20API%20app%20-%20spa%20client%20id.png"/></a></div>
Go back to the API configuration in Azure portal to set CORS for http://localhost:4200
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3W3oVDco37l7zSExVvYDBfqC9CnFJ-52aMBdr9pKDpNJ2dFMmU_NpkbWQmVel8L8obuM5kOghXgyLsIr9Cn-vEBw68Ytky3ucX5y0X3BKDej80fnhFKiTy3nV1HlyJLmhKos_O5G8qwNUAkTT7Bzfi6N3KNVd0y7nUIGFg7C_DQyfWpSRNDwL-t7ca8Bu/s1600/Azure-AD-Angular-SPA-API-MSAL-13-adding%20CORS%20for%20the%20SPA%20to%20the%20API.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="857" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3W3oVDco37l7zSExVvYDBfqC9CnFJ-52aMBdr9pKDpNJ2dFMmU_NpkbWQmVel8L8obuM5kOghXgyLsIr9Cn-vEBw68Ytky3ucX5y0X3BKDej80fnhFKiTy3nV1HlyJLmhKos_O5G8qwNUAkTT7Bzfi6N3KNVd0y7nUIGFg7C_DQyfWpSRNDwL-t7ca8Bu/s1600/Azure-AD-Angular-SPA-API-MSAL-13-adding%20CORS%20for%20the%20SPA%20to%20the%20API.png"/></a></div>
Then, update your ngmodule to add MSAL Guard and MSAL Interceptor:
<PRE>
@NgModule({
declarations: [AppComponent, HomeComponent, ProfileComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
MatButtonModule,
MatToolbarModule,
MatListModule,
HttpClientModule,
MsalModule.forRoot(
// MSAL Configuration V2. Mandatory! V1 outside NgModule no longer works
new PublicClientApplication({
auth: {
clientId: "9fefb62c-5e82-4a09-acc3-ea077f8164f3", // Application (client) ID from the app registration
authority:
"https://login.microsoftonline.com/994d9022-89d7-44f4-91e2-3851290dc50d", // The Azure cloud instance and the app's sign-in audience (tenant ID, common, organizations, or consumers)
redirectUri: "http://localhost:4200/", // This is your redirect URI,
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: isIE,
},
}),
//MSAL guard
{
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ["api://a30c6d65-3d0b-415e-9dc7-4587fae74e2e/user_impersonation"],
},
},
//interceptor Configuration V2. V1 outside NgModule still works but you must add declaration in providers
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
["https://helloworldfunction1123.azurewebsites.net/", [
{
httpMethod: "GET",
scopes: ["api://a30c6d65-3d0b-415e-9dc7-4587fae74e2e/user_impersonation"],
}
]]]),
}
),
],
providers:
[ {
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
} ],
bootstrap: [AppComponent, MsalRedirectComponent],
})
</PRE>
<b>MSAL INTERCEPTOR will generate a token and attach it automatically to the http request when your code will call the API</b>
<br>
Nothing to do while coding, just use an http-client to call the API!
<br>Don't be bothered by the token generation, header setting and all that stuff. It is like magic!
<br>
<br>
<a target='blank' href="https://github.com/MarcCharmois/Angular-V16-MSAL-V2-SPA-API-CALL"><div style="height:20px; width:150px; background-color:#99b3ff;color:white;border-radius:5px; padding:5px;">Get the code</div></a>
I let anyway <a target='blank' href="https://github.com/MarcCharmois/Angular-V16-MSAL-V3-SPA-API-CALL/blob/master/src/app/get-functionResponse.service.ts">commented code in this source code if you want to generate the token and attach it manually to a request.</a>
<pre>
//with http Interceptor of MSAL Angular the token is genrated automatically and attached to
//the http requast so no need to generate it
//uncomment the lines if you want to use the token and see it anyway
async getFunctionResponse() {
let url = "https://helloworldfunction1123.azurewebsites.net/api/powershell-azure-function-helloworldHttpTrigger?";
//let bearer2 = this.accessToken;
let headers = new HttpHeaders()
.set('Content-Type', 'text/html')
//.set('Authorization', 'Bearer ' + bearer2)
console.log("headers:")
console.log(headers)
return this.http.get(url, { headers, responseType: 'text' }).toPromise()
}
</pre>
I let the values of clizent id , tenant id, url of this post in my source code to help you.
<br>
<a target='blank' href="https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-acquire-token?tabs=angular2">Here is the MS doc on this part</a>
<br>
<br>
If everything is configured properly you should have a response from an API in your SPA:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP5wOjZBQ6QVNN2QP7vuDdJbI_bkLb2_AsnsmuNng097mCbNVstpl_WGfT6xSYySIhghmHnbJsfMBpNys57Vh8xHe1OxHGswPXzaCKBZ24U0xrTl-qQtEluyYGuuvMapM9PmT3dh8px-kKbagjp4qxMLt-sH6xrcJWhQBfvnb7mng-Lp1f0H4UYaumJ3vL/s1600/Azure-AD-Angular-SPA-API-MSAL-14-%20API%20call%20from%20the%20SPA%20using%20angular%20MSAL%20worked.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP5wOjZBQ6QVNN2QP7vuDdJbI_bkLb2_AsnsmuNng097mCbNVstpl_WGfT6xSYySIhghmHnbJsfMBpNys57Vh8xHe1OxHGswPXzaCKBZ24U0xrTl-qQtEluyYGuuvMapM9PmT3dh8px-kKbagjp4qxMLt-sH6xrcJWhQBfvnb7mng-Lp1f0H4UYaumJ3vL/s1600/Azure-AD-Angular-SPA-API-MSAL-14-%20API%20call%20from%20the%20SPA%20using%20angular%20MSAL%20worked.png"/></a></div>
Well done!
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-45496010927340849692023-09-16T23:42:00.000+02:002023-09-19T14:16:03.685+02:00Call an Azure AD protected API from a SPA using MSAL JS
<h2>Overview</h2>
This is an upgrade of <a href="https://jannehansen.com/call-aad-functions-from-spa/">this great post</a> from Janne Hansen. Thanks to him. He helped me alot!
<br>
The goal is to autenticate a user with Azure AD on a Single Page Application made with JavaScript, and, from this page, let the user call an Azure API protected with Azure AD while the user has no need to sign in for the API. There is also a notion of Single Sign On (SSO) in there. At the first sign-in user authenticates with Azure AD, then, is also authenticated for the API
<br>
The code of Jane Hansen is available at <a href="https://github.com/jannehansen/SinglePageAndAAD" >GitHub:jannehansen/SinglePageAndAAD</a>
<br>It uses MSAL browser V2, and stil works perferctly well.
<br>
I had to update Janne Hansen's post rather for the steps of Azure cofiguration.
<h2>Authentication Flow - First step</h2>
First, to well configure everything for the solution in Azure Portal and understand the code used for MSAL (either JavaScript or Angular) you need to figure out how the double authentication flow is working.
<br>
For authenticating a user to Azure AD, you have to use Azure AD Applications. Azure AD applications are like super heroes that receives from a user a demand to be authenticated and let the user pass through Azure AD. But as every super heroes their powers are limited. They can act only for a certain scope: after being authenticated, you can be redirected only for the demanded scope, SPA, API, MS online product, SharePoint online, Outlook online etc...
<br>
So, for our solution, first we need two super heroes:
<ul>
<li>one application for the scope of our Single Page Application
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyS0BFWPTa87JKlyU5XolkpOX9hhUhS0HccVlrw-J6u9_jdgu8JgtRaAMY-7aa6JbL6wNL6z2Z1F6OMRcK2VD7QcnQMq74Rmqf2SyVF0G8C2gUKqlQMSvOlUlLweTPvgLC_p58WbfVGCPgfq-CPrczMKzDx2m9zVa-Q0eTnY7q-nDD5nw3aOV19aJ_6f-5/s1600/Azure%20AD%20SPA%20application%20super%20heroe%20with%20dialog.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:17%" alt="" border="0" data-original-height="1296" data-original-width="1296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyS0BFWPTa87JKlyU5XolkpOX9hhUhS0HccVlrw-J6u9_jdgu8JgtRaAMY-7aa6JbL6wNL6z2Z1F6OMRcK2VD7QcnQMq74Rmqf2SyVF0G8C2gUKqlQMSvOlUlLweTPvgLC_p58WbfVGCPgfq-CPrczMKzDx2m9zVa-Q0eTnY7q-nDD5nw3aOV19aJ_6f-5/s1600/Azure%20AD%20SPA%20application%20super%20heroe%20with%20dialog.png"/></a></div>
</li>
</ul>
<li>another application for the scope of our API</li>
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI6_2kDGeMnWw55wBWxOWKGA7GQ3ynUf9K0mfJeRaH3Yp1dItRh0_Cb5GPyap6PgzjOx-5xHegwyY01vjlpyvv9VGPWAeD9o7JvqPifI-gNq_LKeiBca9oh5UbOA6gGtsUcaLszWdiYUeQjOZS2of3trcnj4CVVPit4PP-E9qI6fUJ0vL-zCwYMHPETtLw/s1600/Azure%20AD%20API%20application%20super%20heroe%20with%20dialog.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="450" data-original-width="800" style="width:25%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI6_2kDGeMnWw55wBWxOWKGA7GQ3ynUf9K0mfJeRaH3Yp1dItRh0_Cb5GPyap6PgzjOx-5xHegwyY01vjlpyvv9VGPWAeD9o7JvqPifI-gNq_LKeiBca9oh5UbOA6gGtsUcaLszWdiYUeQjOZS2of3trcnj4CVVPit4PP-E9qI6fUJ0vL-zCwYMHPETtLw/s1600/Azure%20AD%20API%20application%20super%20heroe%20with%20dialog.png"/></a></div>
<h2>Testing this first step</h2>
Clone with git or dwonload the code <a href="https://github.com/jannehansen/SinglePageAndAAD" >GitHub:jannehansen/SinglePageAndAAD</a>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mAC_ZnYEuaMIsCVS5STRR_DZ2ybe4cuBJ_tCliCmXwNXfwbES4Rpq3KnMu3RtNYalBoR08IqVJZ4YoaZwpEKAo5MXOjpCcNDr84Men4ROVGlp8kMvnABIFYLpbz5o1gK5rRxzMfqYIBvO8-pGUW9pimSIarP6geA0IbhL8c1LjtxYrn2Pc69_qRutJSt/s1600/Azure-AD-SPA-API-MSAL-01-code%20downloaded.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="900" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mAC_ZnYEuaMIsCVS5STRR_DZ2ybe4cuBJ_tCliCmXwNXfwbES4Rpq3KnMu3RtNYalBoR08IqVJZ4YoaZwpEKAo5MXOjpCcNDr84Men4ROVGlp8kMvnABIFYLpbz5o1gK5rRxzMfqYIBvO8-pGUW9pimSIarP6geA0IbhL8c1LjtxYrn2Pc69_qRutJSt/s1600/Azure-AD-SPA-API-MSAL-01-code%20downloaded.png"/></a></div>
Install <a href="https://www.npmjs.com/package/http-server">NPM http-server</a>
<br>
Run a command, navigate to the code repository to the folder <b>functioncall</b> and serve the SPA locally by:
<ul>
<li>running http-server
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF0Zu72qZouqTqaLizxYRNz9UQl8BnK79giZZ2GSmvry-txnXgXehueyxT51OjfXxuPThfU3iFnYfKWHGyXYkOp3niz1TkTE_YfJJF2U0QyFKHyDrL-mJhwz8pe6mjOdmbIX2nuWTkyX_7aBCgafO4ZrvuqMC2dYDPl3p4IgtYtBEgkMeXiTi47IsD0Lm9/s1600/ScreenAzure-AD-SPA-API-MSAL-02-http-server%20serve%20the%20SPA.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="621" data-original-width="1107" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF0Zu72qZouqTqaLizxYRNz9UQl8BnK79giZZ2GSmvry-txnXgXehueyxT51OjfXxuPThfU3iFnYfKWHGyXYkOp3niz1TkTE_YfJJF2U0QyFKHyDrL-mJhwz8pe6mjOdmbIX2nuWTkyX_7aBCgafO4ZrvuqMC2dYDPl3p4IgtYtBEgkMeXiTi47IsD0Lm9/s1600/ScreenAzure-AD-SPA-API-MSAL-02-http-server%20serve%20the%20SPA.png"/></a></div>
</li>
<li>calling http://localhost:8080 in a browser
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZTn820EHU7DfWVDCRm_mZuJcfD4v5YlVPI4v3y6ZnNt_y8Wo5-ER5q55aq-wwZNm_uxyYADH4YkvTDmQPnEe5vhNqzWWGd-lpxSxacqqTHQ8W3m2iQosvv1UY3EeYMKlKtChT-bw0kPG0cWWv7_3WV-Ew9Lf7qGeWmv3g8jLzXKXXv5CjvcEuYHzH_Te/s1600/ScreenAzure-AD-SPA-API-MSAL-03-http-server%20serve%20the%20SPA-SPA%20displayed%20in%20browser%20%282%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="515" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZTn820EHU7DfWVDCRm_mZuJcfD4v5YlVPI4v3y6ZnNt_y8Wo5-ER5q55aq-wwZNm_uxyYADH4YkvTDmQPnEe5vhNqzWWGd-lpxSxacqqTHQ8W3m2iQosvv1UY3EeYMKlKtChT-bw0kPG0cWWv7_3WV-Ew9Lf7qGeWmv3g8jLzXKXXv5CjvcEuYHzH_Te/s1600/ScreenAzure-AD-SPA-API-MSAL-03-http-server%20serve%20the%20SPA-SPA%20displayed%20in%20browser%20%282%29.png"/></a></div>
</li>
</ul>
<h2>Configuring the portal for the SPA</h2>
We are now going to create our first superhero for the SPA authentication.
<br>
In Azure Portal, go to Azure Directory.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzod8JPAYgUn07uvycRtOtwmP_2eqLa-F4whPpTx6SvcVHFcDjRXvQXQI5PcrO8JVzCttRJ_j4tXlxzEzK8HnehRFTS9A2YE7NclSkVLchXALGL1kMuBks01qqc3k2tPp_udDurSCgLvxIgvBdG2ZCpUIn7an7nXZ2cP-P-eWOgqOvoTlBQPkQ_Tkbe0CP/s1600/ScreenAzure-AD-SPA-API-MSAL-04-Azure%20Active%20Directory.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="874" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzod8JPAYgUn07uvycRtOtwmP_2eqLa-F4whPpTx6SvcVHFcDjRXvQXQI5PcrO8JVzCttRJ_j4tXlxzEzK8HnehRFTS9A2YE7NclSkVLchXALGL1kMuBks01qqc3k2tPp_udDurSCgLvxIgvBdG2ZCpUIn7an7nXZ2cP-P-eWOgqOvoTlBQPkQ_Tkbe0CP/s1600/ScreenAzure-AD-SPA-API-MSAL-04-Azure%20Active%20Directory.png"/></a></div>
Then, in the left menu, click on "App Registrations", then, click to New Registration:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggqyFe573_3P0-5xmy5AHr2-rriClU8sPOgE19GLbjS6M9aKuwMJWq8Phww1YcdA_umF6QxW-42dQ-Ej35gmy-P6dCvu7jGQSTQhXdfPY8x7tgi8y_K2EpZRv3grp3WtHYK5frzgN9kqPHvm1o8fv8ydrKVyv0I5GqkC6ukDy5Tyo3p3GRul9woyUuM7zz/s1600/ScreenAzure-AD-SPA-API-MSAL-05-SPA%20app%20registration.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" style="width:50%" data-original-height="867" data-original-width="1593" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggqyFe573_3P0-5xmy5AHr2-rriClU8sPOgE19GLbjS6M9aKuwMJWq8Phww1YcdA_umF6QxW-42dQ-Ej35gmy-P6dCvu7jGQSTQhXdfPY8x7tgi8y_K2EpZRv3grp3WtHYK5frzgN9kqPHvm1o8fv8ydrKVyv0I5GqkC6ukDy5Tyo3p3GRul9woyUuM7zz/s1600/ScreenAzure-AD-SPA-API-MSAL-05-SPA%20app%20registration.png"/></a></div>
Then fill the required fields:
<ul>
<li>The App name</li>
<li>Choose SPA as a platform</li>
<li>and http://localhost:8080 as the redirect url</li>
</ul>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFhfCau_2E0Y2WED6b7rpznK8JtbdYqKP2i6wH4ua34sH5X4J3IWbbEDFjfD2xVL4DXG_-imWsMXKve8xJ0NDOIuEUfi_Tkk3vdX-ev_h4jehfRt4Pw0oYAYb5o_tHx7dXyZ17qeptUC10qMHuWP3x1J6I0UCsqDG5PaLUbrkTI0swyluTteSBB_H7HHG8/s1600/Azure-AD-SPA-API-MSAL-05-spa%20app%20registration.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="858" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFhfCau_2E0Y2WED6b7rpznK8JtbdYqKP2i6wH4ua34sH5X4J3IWbbEDFjfD2xVL4DXG_-imWsMXKve8xJ0NDOIuEUfi_Tkk3vdX-ev_h4jehfRt4Pw0oYAYb5o_tHx7dXyZ17qeptUC10qMHuWP3x1J6I0UCsqDG5PaLUbrkTI0swyluTteSBB_H7HHG8/s1600/Azure-AD-SPA-API-MSAL-05-spa%20app%20registration.png"/></a></div>
Once App is created you can see the App overview. Note cerefully the Client Id and the tenant Id.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBGVYeHHwdx3s2PAOR1ZzxG0B_T52WjrYgMioGlLUuVaka21kH38gLkJmHu5wuaSb9VM5wf5oW36FW5QF6xScpWaajirx4fxfsuPn5xUV0mhtQa8yE51KEjN-CN_AOIqsMm7QdDMJv9pJRVRFjvpoOy1NvBY-9jLSC4J6073tPsvQgy6tIiY8mwO-4Gqh8/s1600/ScreenAzure-AD-SPA-API-MSAL-06-SPA%20App%20overview.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="870" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBGVYeHHwdx3s2PAOR1ZzxG0B_T52WjrYgMioGlLUuVaka21kH38gLkJmHu5wuaSb9VM5wf5oW36FW5QF6xScpWaajirx4fxfsuPn5xUV0mhtQa8yE51KEjN-CN_AOIqsMm7QdDMJv9pJRVRFjvpoOy1NvBY-9jLSC4J6073tPsvQgy6tIiY8mwO-4Gqh8/s1600/ScreenAzure-AD-SPA-API-MSAL-06-SPA%20App%20overview.png"/></a></div>
Then, go back to VS Code and update the client Id and the tenant id in your code:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTPn2_jVsNhQQE12CTM49KXAV1Za4okhyd7OnQtDn5kW95riFT4JPRDgQQ7bwAShcRp9z1VpcHVjHK-TXf7fPChPgkP_RyUMlBWQceSORG6fYwaCqqfw4yU3_rV9ZizS9UKdOdJD7fiU0Sr5Z5_443_QL4-QyS9ugg3PGckPx9966d3qWuSOg7TSGGPoOX/s1600/ScreenAzure-AD-SPA-API-MSAL-07-SPA%20App%20AD%20authentication%20code%20config.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTPn2_jVsNhQQE12CTM49KXAV1Za4okhyd7OnQtDn5kW95riFT4JPRDgQQ7bwAShcRp9z1VpcHVjHK-TXf7fPChPgkP_RyUMlBWQceSORG6fYwaCqqfw4yU3_rV9ZizS9UKdOdJD7fiU0Sr5Z5_443_QL4-QyS9ugg3PGckPx9966d3qWuSOg7TSGGPoOX/s1600/ScreenAzure-AD-SPA-API-MSAL-07-SPA%20App%20AD%20authentication%20code%20config.png"/></a></div>
then, click the link to sign in. You will have a pop-up to fill your Azure login and password, and will receive the app demand for permission consent.
<br>
By the way, you will see the App name and you will be sure you were calling the good App.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk4gjc2Q0iMIbdNVfE19IMf7oFb3lDyvOMYYfkSUoMJBZQhpq5X6H_dMPZGSPT6d-Jy5CXVG7gxtPqcKlOMO3XyWb0vgnSmp613MijRKOxRgU6dx4Kc1Z1yBxDKimyiGcp2qUCks6QC7HWmMI5IOoZpHHaFqwe2JP5K0-5z4ClPx6KZcOzOuCzYsZPb5oI/s1600/ScreenAzure-AD-SPA-API-MSAL-08-click%20this%20to%20sign%20in.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="486" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk4gjc2Q0iMIbdNVfE19IMf7oFb3lDyvOMYYfkSUoMJBZQhpq5X6H_dMPZGSPT6d-Jy5CXVG7gxtPqcKlOMO3XyWb0vgnSmp613MijRKOxRgU6dx4Kc1Z1yBxDKimyiGcp2qUCks6QC7HWmMI5IOoZpHHaFqwe2JP5K0-5z4ClPx6KZcOzOuCzYsZPb5oI/s1600/ScreenAzure-AD-SPA-API-MSAL-08-click%20this%20to%20sign%20in.png"/></a></div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimC-C9xPhfc4vF6yhWi2sBeO_OQFOHL93VA4GehARuPKIGoGWEZnj24aCt436pqtr1_zDo-JchohBw2MxD6eY1-epU-q0fYik1yoGsUcL4lb6yFW68gKbTwDtvlGT7NSyrLLur_ixJV7QbvG4EdLnGTY-b6_gY5heX16e4YOtGWaAqIMfFjtfIRLTjrDPS/s1600/ScreenAzure-AD-SPA-API-MSAL-09-App%20permission%20consent.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="862" data-original-width="1094" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimC-C9xPhfc4vF6yhWi2sBeO_OQFOHL93VA4GehARuPKIGoGWEZnj24aCt436pqtr1_zDo-JchohBw2MxD6eY1-epU-q0fYik1yoGsUcL4lb6yFW68gKbTwDtvlGT7NSyrLLur_ixJV7QbvG4EdLnGTY-b6_gY5heX16e4YOtGWaAqIMfFjtfIRLTjrDPS/s1600/ScreenAzure-AD-SPA-API-MSAL-09-App%20permission%20consent.png"/></a></div>
Finally you get signed in and the SPA displays your AAD account information.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimS7FkOAIwQr4-hA2wA9hDFGNNfqqvPEevi5Pi1e7xH4TpZeasw93J8Tb8ExxY5mTmbBbovuj0gGv2ptDFwEvrNDhkGTDD_nHhEDtFuC5HbmwXG8-QjyXBMFW4aTC7p6_24Okk4j_RPc2KVYSbL1LN_HeD6DaTLJ6-xDlsLCI-LMO5OLoDPZrCezA62M5q/s1600/ScreenAzure-AD-SPA-API-MSAL-10-you%20are%20logged%20in.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="519" data-original-width="1540" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimS7FkOAIwQr4-hA2wA9hDFGNNfqqvPEevi5Pi1e7xH4TpZeasw93J8Tb8ExxY5mTmbBbovuj0gGv2ptDFwEvrNDhkGTDD_nHhEDtFuC5HbmwXG8-QjyXBMFW4aTC7p6_24Okk4j_RPc2KVYSbL1LN_HeD6DaTLJ6-xDlsLCI-LMO5OLoDPZrCezA62M5q/s1600/ScreenAzure-AD-SPA-API-MSAL-10-you%20are%20logged%20in.png"/></a></div>
<b>Important: </b> It is super difficult to get rid of cache with this solution using http-server, thus, use systmatically private/incognito windows while doing your tests.
<br>And yes, I know, you will have to sign in for every test, and you may get nervous.
<h2>Configuring the portal for the API</h2>
Now, let's do the part dedicated to the API.
<br>
This time, we are not going to use the Azure Active Directory. We are going to use the configurtaion panes of an existing API within Azure portal.
<br>
If you have an API available in your Azure tenant, go to it.
<br>If you haven't, you can use my <a href="https://mosshowto.blogspot.com/2023/09/get-quickly-azure-api-powershell.html">previous post to quickly build an API based on PowerShell Azure function, then come back to this post. </a>
<br>
<br>
Go to your API configuration within Azure Portal and click on authentication in the left menu
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDRBJOLkCn-o0p6umXkk1bLYSfYXAxJoZeDowNqc1cBBZZEsVN9wLg715xKtdFLRpNZKzTq8utdr7Qf0OeitfsVHxrg4VyagfDyoEqFlMggHf5ejn9rLUI_lVkwJTpKh4zGxPup43qz7we0UjtsbsztYPOzQ2RD3Ry029bGx_gbGUPuBDbgTfEA3Tw_Yt-/s1600/Azure-AD-SPA-API-MSAL-11-API%20congiguration%20Azure%20portal.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="870" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDRBJOLkCn-o0p6umXkk1bLYSfYXAxJoZeDowNqc1cBBZZEsVN9wLg715xKtdFLRpNZKzTq8utdr7Qf0OeitfsVHxrg4VyagfDyoEqFlMggHf5ejn9rLUI_lVkwJTpKh4zGxPup43qz7we0UjtsbsztYPOzQ2RD3Ry029bGx_gbGUPuBDbgTfEA3Tw_Yt-/s1600/Azure-AD-SPA-API-MSAL-11-API%20congiguration%20Azure%20portal.png"/></a></div>
then click on "add identity provider" button
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaD9ixkYOtf46mRbffanZEG-3kj78zJjurPIk2ScgYvSFp-aHlovvtLxGqg1c6UoxjrsENuzfi3rfWRcwXsWO8qArpKckkU76JzAgBoVUcpcsz3-FqvwCV96_2Q4ic369YercQ1zZP2_MsY___lQaoK29KhcKKFyyMUEU2Feon40dj0EVOtTsd-dwagfd1/s1600/Azure-AD-SPA-API-MSAL-12-Api%20configurtaion%20Azure%20Portal%20authentication%20pane.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="862" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaD9ixkYOtf46mRbffanZEG-3kj78zJjurPIk2ScgYvSFp-aHlovvtLxGqg1c6UoxjrsENuzfi3rfWRcwXsWO8qArpKckkU76JzAgBoVUcpcsz3-FqvwCV96_2Q4ic369YercQ1zZP2_MsY___lQaoK29KhcKKFyyMUEU2Feon40dj0EVOtTsd-dwagfd1/s1600/Azure-AD-SPA-API-MSAL-12-Api%20configurtaion%20Azure%20Portal%20authentication%20pane.png"/></a></div>
then choose Microsof as prodider, and let create new app registration checked.
<br>Type your AAD app name.
<br>
<b>Important:</b>It is better to create the API and create the Azure Active Directory App from the API Authentication pane, than create the AAD app first then use it for the API authentification because Azure will configure everything for your API.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn8Q5BD-xwdn1PXumYRXW9oOr39rzLi1uxH0mMLbS6wDVhxE_Dy4QcE0eiZb6yhuzaYMCgA34BM46PoVdJN_YFGY_rwpSi1Q5VSBfwex0t_WYL4rDj688VKhSy0xPLzGusaumn2DplKDI9h9GXFCfBQFTQ6tHEgecrq2mQPwMzI6edpSKth0LV2Ez72VNk/s1600/Azure-AD-SPA-API-MSAL-14-API%20authentication%20app%20name.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="860" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn8Q5BD-xwdn1PXumYRXW9oOr39rzLi1uxH0mMLbS6wDVhxE_Dy4QcE0eiZb6yhuzaYMCgA34BM46PoVdJN_YFGY_rwpSi1Q5VSBfwex0t_WYL4rDj688VKhSy0xPLzGusaumn2DplKDI9h9GXFCfBQFTQ6tHEgecrq2mQPwMzI6edpSKth0LV2Ez72VNk/s1600/Azure-AD-SPA-API-MSAL-14-API%20authentication%20app%20name.png"/></a></div>
Let the other choices by default, even redirect is said not be recommended for API, because we are going to use the redirect later.
<br>
Then your authentication is set API side in the Azure portal.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW9GhDp60Yw4ncF0Tt2Pq_C0zhTPIrxhwJug_Z3AiDZ0KUpawhr5uVCVXQGx_fb9gSidglvzwsblaoSe4g0uu0gxkUJw-K0MXdIqo0hFZo1wwI0que7eX9Ihx5KsfACjkkBAKpb0dveWNwvd-EY4NxSQ6uZjtX6JeAQCp2gxRIN_iTooWYHB1vKJOCjan2/s1600/Azure-AD-SPA-API-MSAL-16-API%20authentication%20AAD%20app%20created.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="868" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW9GhDp60Yw4ncF0Tt2Pq_C0zhTPIrxhwJug_Z3AiDZ0KUpawhr5uVCVXQGx_fb9gSidglvzwsblaoSe4g0uu0gxkUJw-K0MXdIqo0hFZo1wwI0que7eX9Ihx5KsfACjkkBAKpb0dveWNwvd-EY4NxSQ6uZjtX6JeAQCp2gxRIN_iTooWYHB1vKJOCjan2/s1600/Azure-AD-SPA-API-MSAL-16-API%20authentication%20AAD%20app%20created.png"/></a></div>
Now click the name of your AAD app newly created, and you will be redirected to this new app in Azure AD
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjorY-iQ70aG-j1VJQXZf93i2x56kJyehKhkeMCoXoMBnEnDhn-A8VUEqda-RbhqCCmpxP4-xRbjTrFF4HlMlaSSBbWkAduirJRkE9-9qCUq2QLq43guq3uqDAk0RMCSsye4H4Zg9vuIfQAjsVEL8PCLnYN3X8-PX1JX5JxBevA2Pv7m16KpdZf-k634Tqr/s1600/Azure-AD-SPA-API-MSAL-17-API%20authentication%20App%20configuration%20within%20Azure%20portal%20active%20directory.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="858" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjorY-iQ70aG-j1VJQXZf93i2x56kJyehKhkeMCoXoMBnEnDhn-A8VUEqda-RbhqCCmpxP4-xRbjTrFF4HlMlaSSBbWkAduirJRkE9-9qCUq2QLq43guq3uqDAk0RMCSsye4H4Zg9vuIfQAjsVEL8PCLnYN3X8-PX1JX5JxBevA2Pv7m16KpdZf-k634Tqr/s1600/Azure-AD-SPA-API-MSAL-17-API%20authentication%20App%20configuration%20within%20Azure%20portal%20active%20directory.png"/></a></div>
and if you click authentication in the left menu you will see that the redirect link for sign in has been created automatically!
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDZgCW7p4-28mO5B2y1WvAmupVbtGNZ882Q6epA2b3ln52QzZsTHeoqTH9psXc5wQWjQ84yoyxkQOgQgiQIZBQ5js6HIU9YsF4f5MJN-i7ltVUF4kC-YKIhV3SAkP1NVnkuMKskwpFBPPGEYSemolbHrqR-wxLMs-yDp9Oc1PJn-uC7SqNwg3B0pKDC_sK/s1600/Azure-AD-SPA-API-MSAL-18-The%20redirect%20Url%20was%20configured%20automatically.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="870" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDZgCW7p4-28mO5B2y1WvAmupVbtGNZ882Q6epA2b3ln52QzZsTHeoqTH9psXc5wQWjQ84yoyxkQOgQgiQIZBQ5js6HIU9YsF4f5MJN-i7ltVUF4kC-YKIhV3SAkP1NVnkuMKskwpFBPPGEYSemolbHrqR-wxLMs-yDp9Oc1PJn-uC7SqNwg3B0pKDC_sK/s1600/Azure-AD-SPA-API-MSAL-18-The%20redirect%20Url%20was%20configured%20automatically.png"/></a></div>
Now's the time to test that, so paste your API url in a browser and you will be asked to sign in.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5NJa-UfIAHKkga1sdbX99UBwf_X861e9EoYX6K3a-y6QpUoriHm43gA5Tt-pKY1hzcrlx9fJ-dznLuRoos0Oq3LT-r5QEz8N9O8xxGkNeH8uE6_4nmZNvIldoTS4YbLJ07bByr6_NCYESGD-dFplvXY7GKVMfHDlmerV1t4T-Z4Aq49Ist-32vS-1oRH/s1600/Azure-AD-SPA-API-MSAL-19-API%20call%20now%20require%20an%20authentication.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="866" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5NJa-UfIAHKkga1sdbX99UBwf_X861e9EoYX6K3a-y6QpUoriHm43gA5Tt-pKY1hzcrlx9fJ-dznLuRoos0Oq3LT-r5QEz8N9O8xxGkNeH8uE6_4nmZNvIldoTS4YbLJ07bByr6_NCYESGD-dFplvXY7GKVMfHDlmerV1t4T-Z4Aq49Ist-32vS-1oRH/s1600/Azure-AD-SPA-API-MSAL-19-API%20call%20now%20require%20an%20authentication.png"/></a></div>
then, once signed, you will see the app permission consent pop-up and will be able to check that you called the good AAD app to authentify:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9y9pPCR8EYYoG0UO6V6hG5XOUe0uYe0jK005fb_dM13XqjNFS0OOvHQDM6Z-2PQjzxfydUCPPG2Dug1O7HhaQ5H-sBE8VXRBCJxlPlQuDo3KaioNOoxN3Gc-CoeGlVttwLctVAGItFEzUBSG74j35lpI8ohahEfT_XH6UxCS8rOkQW40CtiX93ZxIO78H/s1600/Azure-AD-SPA-API-MSAL-20-aad%20api%20authentication%20we%20are%20sur%20to%20have%20called%20the%20good%20app.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="866" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9y9pPCR8EYYoG0UO6V6hG5XOUe0uYe0jK005fb_dM13XqjNFS0OOvHQDM6Z-2PQjzxfydUCPPG2Dug1O7HhaQ5H-sBE8VXRBCJxlPlQuDo3KaioNOoxN3Gc-CoeGlVttwLctVAGItFEzUBSG74j35lpI8ohahEfT_XH6UxCS8rOkQW40CtiX93ZxIO78H/s1600/Azure-AD-SPA-API-MSAL-20-aad%20api%20authentication%20we%20are%20sur%20to%20have%20called%20the%20good%20app.png"/></a></div>
and finally, after having consent, you'll see your API display its content in the browser.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxNV9pvKZvCw2WA_zsJxKQnbGUCTB1BDXf2TsgZV5a_SMWwztcRAoMiRMnhTm7UFnG010AhsBN71T9RSyVH14zxhERkpuh1_SXhwon6QjTRS5i0TwzQqg_O1IEGaAjdfTCu33WkYWGmAx1t4ZONRZed0os4jBG0b7aE0-0JveiYdPsd8iAv85jSCXF85jO/s1600/Azure-AD-SPA-API-MSAL-22-azure%20api%20aad%20authent%20-%20we%20are%20logged%20in.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="900" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxNV9pvKZvCw2WA_zsJxKQnbGUCTB1BDXf2TsgZV5a_SMWwztcRAoMiRMnhTm7UFnG010AhsBN71T9RSyVH14zxhERkpuh1_SXhwon6QjTRS5i0TwzQqg_O1IEGaAjdfTCu33WkYWGmAx1t4ZONRZed0os4jBG0b7aE0-0JveiYdPsd8iAv85jSCXF85jO/s1600/Azure-AD-SPA-API-MSAL-22-azure%20api%20aad%20authent%20-%20we%20are%20logged%20in.png"/></a></div>
<h2>Single Sign On cofiguration</h2>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1AzzaLr2p88H9-WF98P8j1Y1O-usjkNY9nRDyTvHLHPGxYc05qchdRCmZsCMftc61FMAiuQ225KzCGgEyZNXZlNt1vYIeZSf3-d9otmJeSPLH91oib1HrM-rovpxXll-2HVFL2xWnRXmLiIEU8ddfyBFYMh6NC_P7kjaYsQCASMWDn5wCLvuJuKHHhmjz/s1600/perplexe-images.png" style="display: block; padding: 1em 0; text-align: left;float:left ;padding-right:10px;"><img alt="" border="0" data-original-height="304" data-original-width="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1AzzaLr2p88H9-WF98P8j1Y1O-usjkNY9nRDyTvHLHPGxYc05qchdRCmZsCMftc61FMAiuQ225KzCGgEyZNXZlNt1vYIeZSf3-d9otmJeSPLH91oib1HrM-rovpxXll-2HVFL2xWnRXmLiIEU8ddfyBFYMh6NC_P7kjaYsQCASMWDn5wCLvuJuKHHhmjz/s1600/perplexe-images.png"/></a></div>
<div style="padding-left:15px;width:50%">
<br>
You might say, well, that's fine all that, but if, as you say, the superheroes are stuck in their own perimeters, how can I log in with the SPA superhero and then, be authenticated for the API with the other superhero without signing in a second time? </div>
<div class="separator" style="clear: both;"></div>
That's because Microsoft Azure Active Directory <b>allows superheroes to delegate permissions!</b>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC1OrJdxXcejZcLO5BcB-w2tnuRlHvb2MS1OjqpEktufALGiHeR_JPP2szzvj4b0vzIKuSXMfuMa_iuU5dHiX1J8U4d-ZU6QaF_DkJz1siiLFJaDL1x8Fobgo0vHb8IwBooWvHzx8muNasTRol0A-DMRCZaWtD7CegLofFHR-xRiRt6nhq3NmbaENSxrBN/s1600/AAD%20Delegated%20permissions.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="506" data-original-width="705" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC1OrJdxXcejZcLO5BcB-w2tnuRlHvb2MS1OjqpEktufALGiHeR_JPP2szzvj4b0vzIKuSXMfuMa_iuU5dHiX1J8U4d-ZU6QaF_DkJz1siiLFJaDL1x8Fobgo0vHb8IwBooWvHzx8muNasTRol0A-DMRCZaWtD7CegLofFHR-xRiRt6nhq3NmbaENSxrBN/s1600/AAD%20Delegated%20permissions.png"/></a></div>
Ok, that's funny, but let's be serious, how are you setting that, seriously ?
<br>
It's elementary, my dear Watson
<br>
Go back to the API superhero in AAD and go to Expose API pane. Microsoft has planned this, as you can tell an api what is its client application:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiofWvBex1zCerxyW80YZBCWvijy5-Mbvh83knHXNGBXDfz5Xt2YVbV6u79J417htEZS0RU46ulFcfOKjeWItLrQl24bW8X5-I0aMdM5sbz__R-10plHpjArp3K8SuKOkwywz93jNsB1umEjsLhwtL_ZcLelofihB4-DhSs4dhJuRe6mB53cpvaCfhtT7L0/s1600/Screenshot%20%281292%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiofWvBex1zCerxyW80YZBCWvijy5-Mbvh83knHXNGBXDfz5Xt2YVbV6u79J417htEZS0RU46ulFcfOKjeWItLrQl24bW8X5-I0aMdM5sbz__R-10plHpjArp3K8SuKOkwywz93jNsB1umEjsLhwtL_ZcLelofihB4-DhSs4dhJuRe6mB53cpvaCfhtT7L0/s1600/Screenshot%20%281292%29.png"/></a></div>
Click on the "+"
<br>
check the proposed scope and paste the client id of the SPA AAD app
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUanioDWsqXvV2lLLRrCEGgVkIQZDMmG2ZCSkQAtuXQsbmWDX6VFRTzdZCuFpV-h6YQulWcRJVLav9laA-XxUSNxJWAPPWsJLt1mur6tPDEa7-YQrBWVOUNSyXBt3COorpAmDNwrem6JJCWUmEhzh5qmX7JxsO2SwqIzkLU6UV6GYebzZyLuys8NMGQZAE/s1600/Azure-AD-SPA-API-MSAL-23-azure%20api%20aad%20add%20a%20client%20application%20%282%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="785" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUanioDWsqXvV2lLLRrCEGgVkIQZDMmG2ZCSkQAtuXQsbmWDX6VFRTzdZCuFpV-h6YQulWcRJVLav9laA-XxUSNxJWAPPWsJLt1mur6tPDEa7-YQrBWVOUNSyXBt3COorpAmDNwrem6JJCWUmEhzh5qmX7JxsO2SwqIzkLU6UV6GYebzZyLuys8NMGQZAE/s1600/Azure-AD-SPA-API-MSAL-23-azure%20api%20aad%20add%20a%20client%20application%20%282%29.png"/></a></div>
Here is the final screenshot before saving
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRFWQVkIUw30ETL6NhVN1lvs22KFEivmtQg3dlQZrTWv2SJUa-0AUkGGKWJ0qNcyqcjjnIa-qT1boRd5W4pe7EcCcjWQkXZ7ItSFaWDu1LL5VZsFSvH2FJI9S-UpmvmYNVg5ghh2wsp8UuGcOq8RghJ-25621ws6Ywrjmahr5VK3g-_Q9QAYBIe4vHZTV_/s1600/Azure-AD-SPA-API-MSAL-28-azure%20api%20aad%20add%20a%20client%20application-config%20before%20saving.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="871" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRFWQVkIUw30ETL6NhVN1lvs22KFEivmtQg3dlQZrTWv2SJUa-0AUkGGKWJ0qNcyqcjjnIa-qT1boRd5W4pe7EcCcjWQkXZ7ItSFaWDu1LL5VZsFSvH2FJI9S-UpmvmYNVg5ghh2wsp8UuGcOq8RghJ-25621ws6Ywrjmahr5VK3g-_Q9QAYBIe4vHZTV_/s1600/Azure-AD-SPA-API-MSAL-28-azure%20api%20aad%20add%20a%20client%20application-config%20before%20saving.png"/></a></div>
<h2>CORS</h2>
To access an API from a SPA, this not the only configurations you have to do. You also have to allow the url of the SPA to call the API. This is CORS (Cross-Origin Resource Sharing). Normally an API can only be accessed by an url with the same domain. Here, were are wrong. SPA is http://localhost and API is https://helloworldfunction1123.azurewebsites.net. So we have to authorize http://localhost to call https://helloworldfunction1123.azurewebsites.net.
<br>
So, go back to Azure Portal in the API configurtaion, locate CORS in the left menu and enter http://localhost:8080 as an authorized domain for CORS.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghVC7drVv3-Ig7qZPFKMJRiweK2e4WVAfVJOjybvjD8jgH-Y8sC_f6gFaulYoTNkRL1c7-F7kjeP3wJJ1Gn7XHjeQ11rCKR4V72W-y4-DuH4QNp1Asv5rQwJeHAX8s5QAEzqTj7YOxRXG6qbEXgdrxlHDGYPQ6Q8IfpBKKt4sEyO0S9atEsb9E3_v7X8r3/s1600/Azure-AD-SPA-API-MSAL-29-CORS%20settings%20for%20the%20API.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="865" style="width:50%" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghVC7drVv3-Ig7qZPFKMJRiweK2e4WVAfVJOjybvjD8jgH-Y8sC_f6gFaulYoTNkRL1c7-F7kjeP3wJJ1Gn7XHjeQ11rCKR4V72W-y4-DuH4QNp1Asv5rQwJeHAX8s5QAEzqTj7YOxRXG6qbEXgdrxlHDGYPQ6Q8IfpBKKt4sEyO0S9atEsb9E3_v7X8r3/s1600/Azure-AD-SPA-API-MSAL-29-CORS%20settings%20for%20the%20API.png"/></a></div>
<h2>JavaScript MSAL code side and testing</h2>
Now, everything in Azure is configured properly, we have to replicate this configuration in our MSAL code.
<br>
You have only 2 params to chang in authRedirect.js
The value of the only entry for the scopes table and the url of the API you want to call.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZgxvQ71MVK-QBEVxkCrp34dfIoszYByTUGh0t61hwnKOI9PfEgZedd6TDoxcHqHNcjFVhduoVrl6v3JbKgJ1BIe5RP_vQia-0rpM2Pp0MHaRIlEgIxQ9al2MvuT1_aObtm2zd7hAjV3UEAq9bKJFIZdaTeU-_s7UOFNUv3Lj1S0DXrINa79zMXelOo0MV/s1600/Screenshot%20%281301%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" style="width:50%" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZgxvQ71MVK-QBEVxkCrp34dfIoszYByTUGh0t61hwnKOI9PfEgZedd6TDoxcHqHNcjFVhduoVrl6v3JbKgJ1BIe5RP_vQia-0rpM2Pp0MHaRIlEgIxQ9al2MvuT1_aObtm2zd7hAjV3UEAq9bKJFIZdaTeU-_s7UOFNUv3Lj1S0DXrINa79zMXelOo0MV/s1600/Screenshot%20%281301%29.png"/></a></div>
<a href="https://github.com/MarcCharmois/SPA-API-AAD-MSAL-JS-V2"><div style="height:20px; width:150px; background-color:#99b3ff;color:white;border-radius:5px; padding:5px;">Get the code</div></a>
So now, after the code modification, stop the http-server with ctrl C. Restart it. Open a new inPrivate/Incognito browser window.
<br>
Sign in again to the SPA in if you click the link to the API while signed in:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpCpkBFOTY73VUQp_m5G_GUqduyEDiY0r-RjAwDCyz4HExNagfGopybSBYD194BVGxjRkmdjdD6CNE-eKomxaRN74w-Nz5Wu9CiDDckY_AiVf9mMrWHkeQcaJOk3f4b78Jd7oTXQ8MgfbQ-vdScjNOp0_1wk8UyJP9gDnwds5atiQ6sG6UmOgo7saTgumX/s1600/Screenshot%20%281302%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="476" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpCpkBFOTY73VUQp_m5G_GUqduyEDiY0r-RjAwDCyz4HExNagfGopybSBYD194BVGxjRkmdjdD6CNE-eKomxaRN74w-Nz5Wu9CiDDckY_AiVf9mMrWHkeQcaJOk3f4b78Jd7oTXQ8MgfbQ-vdScjNOp0_1wk8UyJP9gDnwds5atiQ6sG6UmOgo7saTgumX/s1600/Screenshot%20%281302%29.png"/></a></div>
you will have the response of your API displayed:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBxkeQrGdqb_xu8rS5YeRAJPhbzkJOo0C5djNbHvLyqZ9GrGMsPuyUzwd84iQj9YYbD2jf4PYJzHb-_LpRKTKuY4t-Ipq-iT8tCdLSlCaWc1W4ogvEKwvy1QCGf3R-2uCyKsbidigAvxw5HI-OQ8kYa5AtYn8Kd_6ki_v_vfnCksedymi9hW5L_LO1iVTc/s1600/Screenshot%20%281299%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="900" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBxkeQrGdqb_xu8rS5YeRAJPhbzkJOo0C5djNbHvLyqZ9GrGMsPuyUzwd84iQj9YYbD2jf4PYJzHb-_LpRKTKuY4t-Ipq-iT8tCdLSlCaWc1W4ogvEKwvy1QCGf3R-2uCyKsbidigAvxw5HI-OQ8kYa5AtYn8Kd_6ki_v_vfnCksedymi9hW5L_LO1iVTc/s1600/Screenshot%20%281299%29.png"/></a></div>
<h2>To get further</h2>
You noticed I have displayed the second authorization token in the browser console. You can decrypt it using JWT.io.
<br>
You will notice we retrieve the authentication origin with the spa client id and the authorization scope for the API.
<br>
The token is saying: "I come from the spa and request authentication for the API"
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkU6xPJCgRz0d39NyzLTQacIEF_7aF-PyxxDMA83LfNHTnYCp_4uZGq8dirFCWyanF9mYeRcBetjWAAh0fcj5QAzUrppKguUSMN43YUe1cPAKeRqlcUJeLS-Zvp6GCI0N4TuOgV9UUspUOoHoIYGGXTs-nAqsmeijaTQNX5OB7y0YdEphHwNuY4f07q7ym/s1600/Screenshot%20%281300%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkU6xPJCgRz0d39NyzLTQacIEF_7aF-PyxxDMA83LfNHTnYCp_4uZGq8dirFCWyanF9mYeRcBetjWAAh0fcj5QAzUrppKguUSMN43YUe1cPAKeRqlcUJeLS-Zvp6GCI0N4TuOgV9UUspUOoHoIYGGXTs-nAqsmeijaTQNX5OB7y0YdEphHwNuY4f07q7ym/s1600/Screenshot%20%281300%29.png"/></a></div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-85713456526867657582023-09-08T13:04:00.005+02:002023-09-08T13:07:40.575+02:00Get quickly an Azure API (PowerShell-function)For a lot of reasons, you need sometimes to have an API for testing. I had this need recently for testing MSAL with Anguler.
<br>
So, here is a first way to quickly get an Hello World API working in Azure. It is based on Azure function, PowerShell stack.
<br>
<h2>Prerequisites</h2>
<ul>
<li>Access as contributor to an Azure subscription</li>
<li>Visual Studio Code installed within your device</li>
<li>Git installed within your device</li>
</ul>
<h2>Overview</h2>
We are going to use local Azure Function Core Tools to emulate a function locally and deploy it to azure.
<br>
For doing that, we need to:
<ul>
<LI>Download and install <a href='https://dotnet.microsoft.com/en-us/download/dotnet/6.0'>.Net 6 SDK</a></li>
<LI>Download and install <a href='https://go.microsoft.com/fwlink/?linkid=2174087'>Azure Function Core tools</a></li>
<LI>git clone locally <a href='https://github.com/dfinke/powershell-azure-function-helloworld'>a Hello World sample of a PowerShell Function from Github</a></li>
<li>Make it work locally</li>
<li>Create an empty function App in the Azure Portal</li>
<li>Deploy the local code to Azure with Visual Studio code
</ul>
<h2>Install .Net 6</h2>
Go to the <a href='https://dotnet.microsoft.com/en-us/download/dotnet/6.0'>.Net 6 download page</a>
<br>
Install .Net 6
<br>
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhDQSdituSpcDnpXwGMqaKqvQhYMP8CEv5nJEaZGjjkSIGNvGAXCgTuQgDAAhVOUk-fAPsgWls3A7aephbny-p9O-U2FrsUE0REGbhoo9Fv0ZuDCyVrX0MrDThflht5VpUj4sduhYFJRdUJQDU5czETSWln6todBb8zbzPd-Qa1OAdT9n9RbLvG-cT1trG/s1600/Screenshot%20%281%29.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="823" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhDQSdituSpcDnpXwGMqaKqvQhYMP8CEv5nJEaZGjjkSIGNvGAXCgTuQgDAAhVOUk-fAPsgWls3A7aephbny-p9O-U2FrsUE0REGbhoo9Fv0ZuDCyVrX0MrDThflht5VpUj4sduhYFJRdUJQDU5czETSWln6todBb8zbzPd-Qa1OAdT9n9RbLvG-cT1trG/s1600/Screenshot%20%281%29.png"/></a></div>
<h2>Install Azure Function Core Tools</h2>
Click <a href='https://go.microsoft.com/fwlink/?linkid=2174087' >this link to download the installation package</a>
<h2>Clone the Hello World PowerShell function code from Github</h2>
Open a command prompt, locate your DEV directory and execute :
<br>
<pre>
git clone https://github.com/dfinke/powershell-azure-function-helloworld.git
</pre>
<h2>Let VS code install the Azure extension</h2>
You can then open it in Visual Studio code.
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB3E-u2j9ogb7NpoCp2YlB4dC5LYsRqloUf5ZROvN4sfw6kVWRjsfgVduUGuvf3CR67NpCD29_9Kq0r0Cv92C65Jf6_Ese-8HGx1AVcXdBed_xM3OIXoKG91ujyf-rea6-b1mX2KgUSxlhWMusqzbgZKDXSQ2y0_vFVGCy77RgAmdY48gSwrHh-9g7aE1M/s1600/Screenshot%20%283%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="858" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB3E-u2j9ogb7NpoCp2YlB4dC5LYsRqloUf5ZROvN4sfw6kVWRjsfgVduUGuvf3CR67NpCD29_9Kq0r0Cv92C65Jf6_Ese-8HGx1AVcXdBed_xM3OIXoKG91ujyf-rea6-b1mX2KgUSxlhWMusqzbgZKDXSQ2y0_vFVGCy77RgAmdY48gSwrHh-9g7aE1M/s1600/Screenshot%20%283%29.png"/></a></div>
<br>
Visual studio will ask you to install the extension "Azure Function".
Agree, and the extension will be installed and also the other extensions "Azure Resources" and "Azure Account", that allow you to:
<li>sign in to Azure from Visual Studio Code</li>
<li>create new resources into Azure from Visual Studio Code</li>
<li>deploy code to Azure, like this one of the Azure Function PowerShell Hello World</li>
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1FzlOImA0bk9Jtj9PD8DNR4MqCaQIMteu644n9J_zsi6IJAW5K-WBFywDs4SbCMsJ1MWZIqhMoWRNCDOISl-MEvmnRhDpVfUdJZ1--MUXME02GGPCqG5j55Pg_lOTImlEh5azy-YF4TUpu50eRaWqTJVXUtGxmeG8U6HnG-qhbrZj2wevmVWaNdPDeA92/s1600/Screenshot%20%285%29.png" style="display: block; padding: 1em 0; text-align: left; clear: left; float: left;"><img style="width:50%" alt="" border="0" data-original-height="842" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1FzlOImA0bk9Jtj9PD8DNR4MqCaQIMteu644n9J_zsi6IJAW5K-WBFywDs4SbCMsJ1MWZIqhMoWRNCDOISl-MEvmnRhDpVfUdJZ1--MUXME02GGPCqG5j55Pg_lOTImlEh5azy-YF4TUpu50eRaWqTJVXUtGxmeG8U6HnG-qhbrZj2wevmVWaNdPDeA92/s1600/Screenshot%20%285%29.png"/></a></div>
<br>
<h2>Create an empty function into Azure</h2>
Then, sign in to Azure using the Azure Account extension.
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkcaA67ZHZ_6ysXvfWT52c4dmo0O_dbC4Ug8iOWsfq6Wl9EPsWu_CuS8e4n0-GL86rn1r7P_xx1UljPfFtC_0HBqplkX_YOMn8RrhlBevyYVAb14TOGrGPzjZ8eN30yWp9H_UBnY81DrOCLzcOS738GTU_QzQYDTWUsXMiC7CzYkwQxkEczp56E1BEummE/s1600/Screenshot%20%286%29.png" style="display: block; padding: 1em 0; text-align: left; clear: left; float: left;"><img style="width:50%" alt="" border="0" data-original-height="862" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkcaA67ZHZ_6ysXvfWT52c4dmo0O_dbC4Ug8iOWsfq6Wl9EPsWu_CuS8e4n0-GL86rn1r7P_xx1UljPfFtC_0HBqplkX_YOMn8RrhlBevyYVAb14TOGrGPzjZ8eN30yWp9H_UBnY81DrOCLzcOS738GTU_QzQYDTWUsXMiC7CzYkwQxkEczp56E1BEummE/s1600/Screenshot%20%286%29.png"/></a></div>
<br>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwEUZlmQe7tenPQgNQgcQ3V_5A8d7rpshlKVuqadTtxS9ZWyMMBFtaJyqVGefxS3nCYf3C_vI5tYw1_-lgBv8Os3VyCF8V7grsSFB5_EA1j4vhzMDEEFDaJ_U8618kCOCUbGyExl7ND3Wj3K-RbBEM5gLYp0EwwPA9-pPVc4xoFrgSjA_7Z8-mncWXcmeA/s1600/Screenshot%20%287%29.png" style="display: block; padding: 1em 0; text-align: left; clear: left; float: left;"><img alt="" style="width:50%" border="0" data-original-height="900" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwEUZlmQe7tenPQgNQgcQ3V_5A8d7rpshlKVuqadTtxS9ZWyMMBFtaJyqVGefxS3nCYf3C_vI5tYw1_-lgBv8Os3VyCF8V7grsSFB5_EA1j4vhzMDEEFDaJ_U8618kCOCUbGyExl7ND3Wj3K-RbBEM5gLYp0EwwPA9-pPVc4xoFrgSjA_7Z8-mncWXcmeA/s1600/Screenshot%20%287%29.png"/></a></div>
<br>
The Azure Resources extension, then, will show you the subscriptions of your tenant.
<br>
You can click on the "+" to create a new resource
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1nKoiEi-NHZAMtL0wdrkCyCqfXkvU_SD-UXVQL5xChCD93nyDPxTTmdTt2VJoBdr2qCixGiH3Knw40OdY8xO0bXEqPfmPWUlrM4I5RiEnLE6UJZQTRZKa5rDsYAcc55DI_ov31IHHBXz6MtlIdKwfoaDG2dUc3ijyXe5S9UHdJ9-4qyoRJUyUQVLzJlwa/s1600/Screenshot%20%281252%29.png" style="display: block; padding: 1em 0; text-align: left; clear: left; float: left;"><img style="width:50%" alt="" border="0" data-original-height="468" data-original-width="1161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1nKoiEi-NHZAMtL0wdrkCyCqfXkvU_SD-UXVQL5xChCD93nyDPxTTmdTt2VJoBdr2qCixGiH3Knw40OdY8xO0bXEqPfmPWUlrM4I5RiEnLE6UJZQTRZKa5rDsYAcc55DI_ov31IHHBXz6MtlIdKwfoaDG2dUc3ijyXe5S9UHdJ9-4qyoRJUyUQVLzJlwa/s1600/Screenshot%20%281252%29.png"/></a></div>
<br>
<div class="separator" style="clear: both;">
However, we are rather going to use the portal to create the function, because an Azure function needs to have an unqiue name and the portal can validate if our name is unique.
<div style="clear:both"></div>
<br>
So, go to the portal, display the rezsources of one of your subscription and start creating a function by clicking the "+" sign.
<br>
Then search for function app.
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvnOBNUUdNzfToTFFg2YtPjSAhiOe0yTjCxn-fUbZYlRmwF_oSg1B-cO9XrGNI2i8pzeGh5o15MVGPmm4VO-KsElTwpqUcZzh7zlVh1teg-ZUa1JHnughWbaryToYCzkTIvxOFuZ9eh6EDKtbKblcRfOpSSmKalpxgbqPxQy6uihxdwWRM9uijYyl0viZv/s1600/Screenshot%20%281253%29.png" style="display: block; padding: 1em 0; text-align: left; clear: left; float: left;"><img alt="" style="width:50%" border="0" data-original-height="793" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvnOBNUUdNzfToTFFg2YtPjSAhiOe0yTjCxn-fUbZYlRmwF_oSg1B-cO9XrGNI2i8pzeGh5o15MVGPmm4VO-KsElTwpqUcZzh7zlVh1teg-ZUa1JHnughWbaryToYCzkTIvxOFuZ9eh6EDKtbKblcRfOpSSmKalpxgbqPxQy6uihxdwWRM9uijYyl0viZv/s1600/Screenshot%20%281253%29.png"/></a></div>
<br>
Choose a name that doesn't exist, select powershell for the stack, then accept all the following tabs.
<br>
<div class="separator" style="clear: both;">
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxtXagZBHBkrnm2Tx-_TqrxyJGNQ1vHqae85_UrYCX2CHjMeHNyhru4B7y4Ci-ghu2qkayFANC4uim6BfQ5ngkqi7J32DCMmC9ntw7sGy9RyYiCq5A3Ml0Sc37OuQh0i0SV-bfqTgSAhKm0w2ZvSlFPogHfZxAdGtmlfkHrcVgz__SBVkWnOsLWGejgnP/s1600/Screenshot%20%281256%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="796" style="width:50%" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxtXagZBHBkrnm2Tx-_TqrxyJGNQ1vHqae85_UrYCX2CHjMeHNyhru4B7y4Ci-ghu2qkayFANC4uim6BfQ5ngkqi7J32DCMmC9ntw7sGy9RyYiCq5A3Ml0Sc37OuQh0i0SV-bfqTgSAhKm0w2ZvSlFPogHfZxAdGtmlfkHrcVgz__SBVkWnOsLWGejgnP/s1600/Screenshot%20%281256%29.png"/></a></div>
When your function creation is complete, click "go to the resource"
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFOg2_Ifvm1P7TRHPaAPR8dnsJ1TKrtKL3F0cPxUZiOUgCmbnN4YxLSuJ_kMVfSyltDgmzKZ-OC0LCFuMw7vJCiHqhBImDB6G7u5vH8UJbDcBHaI5bFco3ZVYYcrABetF4VM2qeswK4EdahcqOolWFLo1GSlDIO5k6p-f1JNNpg6mWO-Y0ZKSJ-TkQaNPC/s1600/Screenshot%20%281257%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="800" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFOg2_Ifvm1P7TRHPaAPR8dnsJ1TKrtKL3F0cPxUZiOUgCmbnN4YxLSuJ_kMVfSyltDgmzKZ-OC0LCFuMw7vJCiHqhBImDB6G7u5vH8UJbDcBHaI5bFco3ZVYYcrABetF4VM2qeswK4EdahcqOolWFLo1GSlDIO5k6p-f1JNNpg6mWO-Y0ZKSJ-TkQaNPC/s1600/Screenshot%20%281257%29.png"/></a></div>
You will find the Url of your Function App. And if you click it, it will respond while there is not working API yet.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ3-ayZ91n-xK_hbZymu8BRhCQuPGMdeDMQSOzCIvmVkP7SSACbMa4OH7sCaw0PXCv_u1LpB86XdDFWUj-_WBe9olm7s6xLSp7FfRL9B4FxqiCpfCtW7Kr55jEKYUR34snka9nsCiYtl-ncDlmtvCrllUN3lmd8qaA2jUVqq_jF2hzmvFFSEBYrNKtTNPk/s1600/Screenshot%20%281258%29.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="798" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ3-ayZ91n-xK_hbZymu8BRhCQuPGMdeDMQSOzCIvmVkP7SSACbMa4OH7sCaw0PXCv_u1LpB86XdDFWUj-_WBe9olm7s6xLSp7FfRL9B4FxqiCpfCtW7Kr55jEKYUR34snka9nsCiYtl-ncDlmtvCrllUN3lmd8qaA2jUVqq_jF2hzmvFFSEBYrNKtTNPk/s1600/Screenshot%20%281258%29.png"/></a></div>
<br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikdalw_oBWKLVw4jhPagFSf1UidbLyb-Ux02DXy2zu2mZNIPQu6YbCP1rrZcXtcJ37IwgOxvzzXJixvl3DdQBRvBmtzoBrhM2Q8FOsHrEMtbrs0L77aaghUCp0rOSOCW_cEsZzctZ1_kWhusK5C1716mI0qRDZ1TgdCb-aDwHASyAghojwFVmsjqt4xb00/s1600/Screenshot%20%281259%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="790" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikdalw_oBWKLVw4jhPagFSf1UidbLyb-Ux02DXy2zu2mZNIPQu6YbCP1rrZcXtcJ37IwgOxvzzXJixvl3DdQBRvBmtzoBrhM2Q8FOsHrEMtbrs0L77aaghUCp0rOSOCW_cEsZzctZ1_kWhusK5C1716mI0qRDZ1TgdCb-aDwHASyAghojwFVmsjqt4xb00/s1600/Screenshot%20%281259%29.png"/></a></div>
<h2>execute the function locally</h2>
<br>
Go back to your local environment, and, from the command prompt navigate to the code directory
<pre>
cd "powershell-azure-function-helloworld"
</pre>
launch the function
<pre>
func start
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWMEUvjmGx0H-vwgrLfYPgy9-tiGaYo07siTr4pj1DnAjjv8NoxORr3qn31D7qbQHcxMJe8q52_vO7XYnHiQI6-bOHR3AXJJg8_hRiJWCumm0kiUr1EPzJH3q8VecXPsP8yqC0IuMsF1qB5ITLPIIjD129ECTq5K5Fh4I8PB2UFOGC6zFbdtsS3pzOd1J/s1600/Screenshot%20%282%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" style="width:50%" data-original-height="477" data-original-width="975" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWMEUvjmGx0H-vwgrLfYPgy9-tiGaYo07siTr4pj1DnAjjv8NoxORr3qn31D7qbQHcxMJe8q52_vO7XYnHiQI6-bOHR3AXJJg8_hRiJWCumm0kiUr1EPzJH3q8VecXPsP8yqC0IuMsF1qB5ITLPIIjD129ECTq5K5Fh4I8PB2UFOGC6zFbdtsS3pzOd1J/s1600/Screenshot%20%282%29.png"/></a></div>
If you paste into a browser `http://localhost:7071/api/powershell-azure-function-helloworldHttpTrigger` you will see the function API working locally:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6PVvUn-GrQkTInDX5PxItWp9Ct3G15TPhnX7GQfy1_QDYwtfPUv4RCw4kf2Vvq21CrkTEfLnrP03MNsl8IKxWiU9dcMt2r1WNqr6Q2n0VSygb4Su4iD8nKbv7_LZVucNgJOxHRHzDShOQqRQoO_PF3y483it_SaLESZQ43ZCmw_FNv-_adIH5eSn6DEm1/s1600/Screenshot%20%284%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="225" style="width:50%" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6PVvUn-GrQkTInDX5PxItWp9Ct3G15TPhnX7GQfy1_QDYwtfPUv4RCw4kf2Vvq21CrkTEfLnrP03MNsl8IKxWiU9dcMt2r1WNqr6Q2n0VSygb4Su4iD8nKbv7_LZVucNgJOxHRHzDShOQqRQoO_PF3y483it_SaLESZQ43ZCmw_FNv-_adIH5eSn6DEm1/s1600/Screenshot%20%284%29.png"/></a></div>
<h2>Deploy the function code into Azure</h2>
Now that we have an empty function within Azure, we can use VS code to deploy our local code into it.
<br>
Go back to VS code and right click the subfolder of the code of the PowerShell function : powershell-azure-function-helloworldHttpTrigger
<br>
Then, at the bottom of the context menu: "deploy to function App"
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUFkWdlSwx1PZTT8s8X9hfoyysUtBvlMezaFR5fpF-nBBgvd4c9-DgYPfBUN8pFirYHI7S2WDme2bgKAEaEEUAV27sfqUTlJXShLqMDxO8P19AwauhBr7FlIr8xq51ZS4YosJqYg0Im8aFZnRBLht4ZHZDRDaj5ftGazXaMlDJ8GPP-dOSbS0lmqvZhsG/s1600/Screenshot%20%2822%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="863" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUFkWdlSwx1PZTT8s8X9hfoyysUtBvlMezaFR5fpF-nBBgvd4c9-DgYPfBUN8pFirYHI7S2WDme2bgKAEaEEUAV27sfqUTlJXShLqMDxO8P19AwauhBr7FlIr8xq51ZS4YosJqYg0Im8aFZnRBLht4ZHZDRDaj5ftGazXaMlDJ8GPP-dOSbS0lmqvZhsG/s1600/Screenshot%20%2822%29.png"/></a></div>
You can then, choose the subscription where the Azure function you want to deploy to, is:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHYF0C0_afUn1b9kx-ybT_IFQmdI_SCFX8IXSo8lrBzYVuFijRnZFPmRwvJ5oFGwr45bJOWcV4LxqRoRSt4h9shPQHrhdFDvnl9mEyQ7nsifEw2ndKrIAa3TQ-sUvoyc5GB_cvXtBbRVb6EFaLfyXjHGzvcTtVztdUsjPaxIycWoGMrsZaPy0M0d0zDWSv/s1600/Screenshot%20%2823%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="767" data-original-width="1031" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHYF0C0_afUn1b9kx-ybT_IFQmdI_SCFX8IXSo8lrBzYVuFijRnZFPmRwvJ5oFGwr45bJOWcV4LxqRoRSt4h9shPQHrhdFDvnl9mEyQ7nsifEw2ndKrIAa3TQ-sUvoyc5GB_cvXtBbRVb6EFaLfyXjHGzvcTtVztdUsjPaxIycWoGMrsZaPy0M0d0zDWSv/s1600/Screenshot%20%2823%29.png"/></a></div>
Then, we locate the helloworldfunction1123 we have previously created in Azure:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1rLeL_n402LmvYgxIJLQ3dTA5taADCmatFWYgaEq-RLjMbep1XsDClaU6j5_GW21tzEBMZQ2WZ8-v580ZO9E7UZKrRbvQ7WMIfqRNPDnKdoNayKc-Rc4Kg2-jY-IohK3xW8pI8fSjJE5JlOiNqtarCaXDsREmqrXxD_QmLBUcNijChDGh6200MhNc8a1q/s1600/Screenshot%20%2824%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="775" style="width:50%" data-original-width="1027" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1rLeL_n402LmvYgxIJLQ3dTA5taADCmatFWYgaEq-RLjMbep1XsDClaU6j5_GW21tzEBMZQ2WZ8-v580ZO9E7UZKrRbvQ7WMIfqRNPDnKdoNayKc-Rc4Kg2-jY-IohK3xW8pI8fSjJE5JlOiNqtarCaXDsREmqrXxD_QmLBUcNijChDGh6200MhNc8a1q/s1600/Screenshot%20%2824%29.png"/></a></div>
We accept to deploy:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJAEVepk8xLei_ZzSRbOYtPEgMXHpmqiunKwLVTxFGuRSyH4-1o3vIs6wyCbjwrIAJGgMZerlTJhkvpUbFsjgttnKZVvTGW1TlXCyqxkQHfvHGXEzc8UyeGySy4QmyEm3PI9ZiK-57NnDt8cse0kSHBMI5kewPX8KCYPWXL3vi3aVeNwKzHRxfUZDLvQxS/s1600/Screenshot%20%2825%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="773" data-original-width="1025" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJAEVepk8xLei_ZzSRbOYtPEgMXHpmqiunKwLVTxFGuRSyH4-1o3vIs6wyCbjwrIAJGgMZerlTJhkvpUbFsjgttnKZVvTGW1TlXCyqxkQHfvHGXEzc8UyeGySy4QmyEm3PI9ZiK-57NnDt8cse0kSHBMI5kewPX8KCYPWXL3vi3aVeNwKzHRxfUZDLvQxS/s1600/Screenshot%20%2825%29.png"/></a></div>
And, finally, we can see the deployment in action:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlCv-0QRkOikPCdYE9nhxYfDerdQBQkbxnZvBOdfztZrH76tG2W7i5mlBD4uUlB2bBvMfuoR44NszeUGn8HkfSsGUWqErJz3lLIhoFcXcFpFz9Ycq37LHl0Fq4T3wR_lW30cm8EHRMvzI1Q3w_Rq832MX25mU-1n386Tz3A6g2pgvADLxqlblPrxCeGkuh/s1600/Screenshot%20%2826%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" style="width:50%" border="0" data-original-height="775" data-original-width="1024" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlCv-0QRkOikPCdYE9nhxYfDerdQBQkbxnZvBOdfztZrH76tG2W7i5mlBD4uUlB2bBvMfuoR44NszeUGn8HkfSsGUWqErJz3lLIhoFcXcFpFz9Ycq37LHl0Fq4T3wR_lW30cm8EHRMvzI1Q3w_Rq832MX25mU-1n386Tz3A6g2pgvADLxqlblPrxCeGkuh/s1600/Screenshot%20%2826%29.png"/></a></div>
And follow it in the Output pane of VS code untill it is complete:
<br><b>BTW: I had to deploy twice to get it complete. It failled the first time</b>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmcoFgDrLl1eOuorkqNrPRqrOgDy7PfJJY6rTJ2jT74j6SSd2wxbAroxyOzDErRBo2RbBaaFtOFMB_xgMRwifLAFnD7WY79dpDz6TdIRXdO1bC8oaaDDIq5jSNPzDMkHAGzAuWbV6RkoIc50eCpinH5PorDLRC5UUXMxRWW-zgVlI8-RyOoBTGbr4AhnAJ/s1600/Screenshot%20%2827%29.png" style="display: block; padding: 1em 0; text-align: left; "><img style="width:50%" alt="" border="0" data-original-height="868" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmcoFgDrLl1eOuorkqNrPRqrOgDy7PfJJY6rTJ2jT74j6SSd2wxbAroxyOzDErRBo2RbBaaFtOFMB_xgMRwifLAFnD7WY79dpDz6TdIRXdO1bC8oaaDDIq5jSNPzDMkHAGzAuWbV6RkoIc50eCpinH5PorDLRC5UUXMxRWW-zgVlI8-RyOoBTGbr4AhnAJ/s1600/Screenshot%20%2827%29.png"/></a></div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkLf5_Z2sFrtt3GUfs44XyZ-41PXiY9B6poSwLBKsl1cGRZG6CxtjafJMxvx_gGzkuK1ELlRxO-k-orDr4UcVTRzyZQ4jjFa7_4PmKZWbroEG8Y683usL-o2im9VHxVff1IW13EpQ8ExVH5BSY0_iB8JYBy2m58qfIZG4chG1WdrMVsIWcvVbky5nS5VPi/s1600/Screenshot%20%2828%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="868" style="width:50%" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkLf5_Z2sFrtt3GUfs44XyZ-41PXiY9B6poSwLBKsl1cGRZG6CxtjafJMxvx_gGzkuK1ELlRxO-k-orDr4UcVTRzyZQ4jjFa7_4PmKZWbroEG8Y683usL-o2im9VHxVff1IW13EpQ8ExVH5BSY0_iB8JYBy2m58qfIZG4chG1WdrMVsIWcvVbky5nS5VPi/s1600/Screenshot%20%2828%29.png"/></a></div>
Now, if we go back to Azure portal, we can see our PowerShell function avaolable:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_t4732Z-cyaQgHT6YMpA7Icaro2QtmGXc95oruw16BeixLvG_NMcB2fE-6zVV6mmvJwtXKIjiGKfV5jlrE81QAqgVCXPmwmNg5rxe2kTlXR_ZGCA437ZqKWHrumzUDvAQkBt_VG5Cw4791-uc9qgAQYWPRYzXFdmEAyeGsbTyQiW3pB65NL5u_6W6Wu5H/s1600/Screenshot%20%281260%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="800" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_t4732Z-cyaQgHT6YMpA7Icaro2QtmGXc95oruw16BeixLvG_NMcB2fE-6zVV6mmvJwtXKIjiGKfV5jlrE81QAqgVCXPmwmNg5rxe2kTlXR_ZGCA437ZqKWHrumzUDvAQkBt_VG5Cw4791-uc9qgAQYWPRYzXFdmEAyeGsbTyQiW3pB65NL5u_6W6Wu5H/s1600/Screenshot%20%281260%29.png"/></a></div>
If we click on the Name Link of our function, we are redirected to a view where we can get the function Url to call it:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb3BKhw4I2umCKkP9Rgwk9VffCezvNB4rFOh_G0bI0mRA6lSSzIVZV8g3fQDjf5cEmlkpRPn3k93QtI4pzPTdS2ulCShR9NHmvHYLGzEYIcXfnBIsQ0s4XxOGXIX22OSz5lkCRBKBUEnFv3USWRCYQGA8FbstHc3o9k4bXyjx85GqBiQt5MS11BQFhv9lJ/s1600/Screenshot%20%281262%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="796" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb3BKhw4I2umCKkP9Rgwk9VffCezvNB4rFOh_G0bI0mRA6lSSzIVZV8g3fQDjf5cEmlkpRPn3k93QtI4pzPTdS2ulCShR9NHmvHYLGzEYIcXfnBIsQ0s4XxOGXIX22OSz5lkCRBKBUEnFv3USWRCYQGA8FbstHc3o9k4bXyjx85GqBiQt5MS11BQFhv9lJ/s1600/Screenshot%20%281262%29.png"/></a></div>
and if we paste the link in a browser, our function is responding and sends us the content:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOxYUF237tkh4Cg843G9nlZ50thlmz_zUDKgJ3lNxf_TZRo1tbfT1NTv8qABne-JGWpGF7_TPqI6fzD5uaWvJLSVA2zV3bTWZUy-TcdVs6a-gWsfgx5bCERLGblCQUhLD7jprvsrOMgRfy5J7n3cFQPoxA9uE9tW8syk0P_znytPWbCLNzzBObPPLyMhEb/s1600/Screenshot%20%281264%29.png" style="display: block; padding: 1em 0; text-align: left; "><img alt="" border="0" data-original-height="388" data-original-width="1600" style="width:50%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOxYUF237tkh4Cg843G9nlZ50thlmz_zUDKgJ3lNxf_TZRo1tbfT1NTv8qABne-JGWpGF7_TPqI6fzD5uaWvJLSVA2zV3bTWZUy-TcdVs6a-gWsfgx5bCERLGblCQUhLD7jprvsrOMgRfy5J7n3cFQPoxA9uE9tW8syk0P_znytPWbCLNzzBObPPLyMhEb/s1600/Screenshot%20%281264%29.png"/></a></div>
We have now an API in Azure based on PowerShell function that we can use for testing purpose, like authentication, MSAL, etc.
<br>
Well done!
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-14495827377814592552019-09-13T00:22:00.000+02:002019-09-13T00:46:58.520+02:00Build locally a docker image and deploy it to an Azure Web App for containers <div class="h2-paragraph">
<h2>Topic</h2>
this post shows how to locally build a Docker image on <b>Windows 10 Home version</b>, push it to an Azure Container Registry, then, deploy it manually to a Web App for containers so as it can be consume.
<br>
<h2>Prerequisites</h2>
you must have:
<ul>
<li>an access to the Azure Portal</li>
<li>an available Azure Container registry (if not <a href="https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal">do this quick tutorial to have one</a>)</li>
<li><a href="https://runnable.com/docker/install-docker-on-windows-10">Docker Toolbox</a>
<br>
On Windows 10 home version you won't be allowed to install Docker desktop by the Docker installation program but it will install Docker Toolbox that is enough to do the main tasks. </li>
</ul>
<h2>Building the docker image locally</h2>
If you have a github account fork the following repo and clone it on your computer, if not, download the code:
<br>
<a href="https://github.com/Azure-Samples/acr-build-helloworld-node">acr-build-helloworld-node</a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlNbF3w81EUJiGSodVGrpNYUEDN4UBlbFRo5h-KIyEx0fK5jr7v0ThY8HYv98oGFxsr0SGp126HF6JjRlRnbuAhJi8pV12ZggrDPjpKL136YXkeiTR3OnlBBbUdi2ArgQOTPNp3axL29br/s1600/build-docker-image-deploy-WebApp-container+-+00+-+folder+cloned.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlNbF3w81EUJiGSodVGrpNYUEDN4UBlbFRo5h-KIyEx0fK5jr7v0ThY8HYv98oGFxsr0SGp126HF6JjRlRnbuAhJi8pV12ZggrDPjpKL136YXkeiTR3OnlBBbUdi2ArgQOTPNp3axL29br/s1000/build-docker-image-deploy-WebApp-container+-+00+-+folder+cloned.png" class ="screenshot-standard"/></a>
<br>
<br>
Let's examine the content a bit. First it is a real Node.js application even if it's render only "Hello World". It is a good base for future developments for an API and a good way to test the deployment as a container.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikh-dIa3QpCBy-zWtmsJO5pILQAFcKKWiavv7yC4MZS-cRPKy27u3QdD6d5DCRz2eJwgQkrDDxZjE6X3fLgmOUDn6RK_1iWSDs_cRNBpjqBTEc-ok2w6i7cn6NXD-3yHu_USa-_nw60fL7/s1600/build-docker-image-deploy-WebApp-container+-+02+-+real+plask+api.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikh-dIa3QpCBy-zWtmsJO5pILQAFcKKWiavv7yC4MZS-cRPKy27u3QdD6d5DCRz2eJwgQkrDDxZjE6X3fLgmOUDn6RK_1iWSDs_cRNBpjqBTEc-ok2w6i7cn6NXD-3yHu_USa-_nw60fL7/s1000/build-docker-image-deploy-WebApp-container+-+02+-+real+plask+api.png" class ="screenshot-large" /></a>
<br>
<br>
we can see next the files that compose the image. the Dockerfile-base:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7wLEmInG3-k9ZlfrhkJbnBdPx8iRF2Z33vk_Irp1_Ss-Fgvhe_RKHzpx-bzB0vhFKSMW9-uJs1wAJnT5eOBweOX9NvUrbw-zCQ338dWKohSl4c6jWKFemExBByIGGEFYdmQyuTMCS7w4S/s1600/build-docker-image-deploy-WebApp-container+-+04+-+dockerfile-base.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7wLEmInG3-k9ZlfrhkJbnBdPx8iRF2Z33vk_Irp1_Ss-Fgvhe_RKHzpx-bzB0vhFKSMW9-uJs1wAJnT5eOBweOX9NvUrbw-zCQ338dWKohSl4c6jWKFemExBByIGGEFYdmQyuTMCS7w4S/s1000/build-docker-image-deploy-WebApp-container+-+04+-+dockerfile-base.png" class ="screenshot-large" /></a>
<br>
<br>
The Dockerfile-app:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-1cMsegmnRQIZ_JOyDwOE5ho4UcnnwHxo2c65Vf1O9x1mhbsnzMpQv6IiQg-CuMUUx2CbB0POb-vr7jEG1MDvw_2baJu9ovxQ5IQL6j52Q7PJ-LsPj8lrL4vwJGLM96FRdwN2hBqC1JGR/s1600/build-docker-image-deploy-WebApp-container+-+06+-+Dockerfile-app.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-1cMsegmnRQIZ_JOyDwOE5ho4UcnnwHxo2c65Vf1O9x1mhbsnzMpQv6IiQg-CuMUUx2CbB0POb-vr7jEG1MDvw_2baJu9ovxQ5IQL6j52Q7PJ-LsPj8lrL4vwJGLM96FRdwN2hBqC1JGR/s1000/build-docker-image-deploy-WebApp-container+-+06+-+Dockerfile-app.png" class ="screenshot-large"/></a>
<br>
<br>
and most of all the Dockerfile, the only file we really need to build locally a docker image. It tells Docker to:
<ul>
<li> build a machine based on Linux alpine with Node engine included. </li>
<li>copy all the files in src folder</li>
<li>change directory to src folder and perform an NPM install</li>
<li>and the node excution for the API is dedicated to the file server.js located in the src folder</li>
</ul>
Five lines of code an we have a complete environment running an API! Remember how long it took to have the same with a VM...
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTp1nVynD5I4qLxgJpjPVJWt-2sedVRVX0li2FI2FoszMKG4SP-H-ry7Q6qAZPxUVq2-rL9fSoYbt47mWvtBqhnaWHd5GqGGZOV6EXxm4Od7MIZi6aQSGkxxNmWG3U0xpL4qFJIxmXt58q/s1600/build-docker-image-deploy-WebApp-container+-+08+-+dockerfile.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTp1nVynD5I4qLxgJpjPVJWt-2sedVRVX0li2FI2FoszMKG4SP-H-ry7Q6qAZPxUVq2-rL9fSoYbt47mWvtBqhnaWHd5GqGGZOV6EXxm4Od7MIZi6aQSGkxxNmWG3U0xpL4qFJIxmXt58q/s1000/build-docker-image-deploy-WebApp-container+-+08+-+dockerfile.png" class ="screenshot-large"/></a>
<br>
<br>
Now is the time to create the image, so open a command prompt and change directory to the one where is the API code and execute the following:
<pre class="code-standard">
docker build -t nodeapp .
</pre>
<br>
The image is mounted. We can see docker doing all the jobs described previously:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPSqqkTRPQ06TzA4-0nDhXXK_9fvfQynkIWMEBs07rj-rmaeh_Eh037Af3wXcgnJA1yioSZBygWUh3vrx7xFIzwedVBE6uiCF-OpMCoPfrpDxXx4AzlLM50EkSPQBBKL94ROsyYOOD9PuL/s1600/build-docker-image-deploy-WebApp-container+-+08+-+build+image.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPSqqkTRPQ06TzA4-0nDhXXK_9fvfQynkIWMEBs07rj-rmaeh_Eh037Af3wXcgnJA1yioSZBygWUh3vrx7xFIzwedVBE6uiCF-OpMCoPfrpDxXx4AzlLM50EkSPQBBKL94ROsyYOOD9PuL/s1000/build-docker-image-deploy-WebApp-container+-+08+-+build+image.png" class ="screenshot-standard" /></a>
<br>
<br>
then we can run the image:
<br>
<pre class="code-standard">
docker run -p 8888:80 nodeapp
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9NWjfded7cz6UdwSGWL-GEe_Q_qifcwWn9COVpFXnO-1mRIWn_8tEDYHXVFfqyMspl9aesAWptYyo-t5w4vU5cL-vXCEUZUMWMbhJNbBlPDNkQOa_HwkkwaohXD8gP_2ZZ5WisvZlLmI/s1600/build-docker-image-deploy-WebApp-container+-+09+-+run+container.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9NWjfded7cz6UdwSGWL-GEe_Q_qifcwWn9COVpFXnO-1mRIWn_8tEDYHXVFfqyMspl9aesAWptYyo-t5w4vU5cL-vXCEUZUMWMbhJNbBlPDNkQOa_HwkkwaohXD8gP_2ZZ5WisvZlLmI/s1000/build-docker-image-deploy-WebApp-container+-+09+-+run+container.png" class ="screenshot-standard" /></a>
<br>
<br>
for testing the image locally, because we are using Docker Toolbox, we need the IP to request. It is in the Docker Toolbox command:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVbs-puA7EknZshBviTTuBkhhd4-0ENFONk66a71dPSw1eo7qa13u2q2URWV7wTl6dL0f3iqBps_BFY_jm1t0Owgmbx2Y72dzQwo5Gh1dzjqWxNqoW3IBjmdMgIsoGC6eJl7nevuxT4Kkw/s1600/build-docker-image-deploy-WebApp-container+-+12+-+get+the+local+ip+address.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVbs-puA7EknZshBviTTuBkhhd4-0ENFONk66a71dPSw1eo7qa13u2q2URWV7wTl6dL0f3iqBps_BFY_jm1t0Owgmbx2Y72dzQwo5Gh1dzjqWxNqoW3IBjmdMgIsoGC6eJl7nevuxT4Kkw/s1000/build-docker-image-deploy-WebApp-container+-+12+-+get+the+local+ip+address.png" class ="screenshot-large" /></a>
<br>
<br>
As we have set the port to 8888 we can test the running image locally:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQpBQcgjDsIu05eL6aFzlKf9eLpHfd72sKne1vReMNctK6l3fwqF4TugifmUEE3BgInU-VgFDmx1-FmQ4KJTK9aaIOjeXOimiMD9u2KoLbS30ezDHp9WjebPJnn2lU8-6007UBgCJyGgGG/s1600/build-docker-image-deploy-WebApp-container+-+14+-+testing+the+docker+container+locally.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQpBQcgjDsIu05eL6aFzlKf9eLpHfd72sKne1vReMNctK6l3fwqF4TugifmUEE3BgInU-VgFDmx1-FmQ4KJTK9aaIOjeXOimiMD9u2KoLbS30ezDHp9WjebPJnn2lU8-6007UBgCJyGgGG/s1000/build-docker-image-deploy-WebApp-container+-+14+-+testing+the+docker+container+locally.png" class ="screenshot-standard" /></a>
<br>
<br>
Last we can execute a command to list the containers and see hte latest one
<pre class="code-standard">
docker container ls
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9NWjfded7cz6UdwSGWL-GEe_Q_qifcwWn9COVpFXnO-1mRIWn_8tEDYHXVFfqyMspl9aesAWptYyo-t5w4vU5cL-vXCEUZUMWMbhJNbBlPDNkQOa_HwkkwaohXD8gP_2ZZ5WisvZlLmI/s1600/build-docker-image-deploy-WebApp-container+-+09+-+run+container.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9NWjfded7cz6UdwSGWL-GEe_Q_qifcwWn9COVpFXnO-1mRIWn_8tEDYHXVFfqyMspl9aesAWptYyo-t5w4vU5cL-vXCEUZUMWMbhJNbBlPDNkQOa_HwkkwaohXD8gP_2ZZ5WisvZlLmI/s1000/build-docker-image-deploy-WebApp-container+-+09+-+run+container.png" class ="screenshot-standard" /></a>
<br>
<br>
<h2>Pushing Container to Azure</h2>
Now is the time to connect to the Container Registry where to push our Container
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxSxvub4KprpWMezrFwaQM3Fo_OuwOwbe1HfpFsr9lP3DI93OvugeC5nLBJjk8GmHKeJtsstJeDX2lyEJC73e1zrhb6vUatw1EU5_GvPEkrbuw52wDsW3jQCxuWi2BRZWj1vjhm2QIN4Uf/s1600/build-docker-image-deploy-WebApp-container+-+18+-+Azure+Container+Registry.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxSxvub4KprpWMezrFwaQM3Fo_OuwOwbe1HfpFsr9lP3DI93OvugeC5nLBJjk8GmHKeJtsstJeDX2lyEJC73e1zrhb6vUatw1EU5_GvPEkrbuw52wDsW3jQCxuWi2BRZWj1vjhm2QIN4Uf/s1000/build-docker-image-deploy-WebApp-container+-+18+-+Azure+Container+Registry.png" class ="screenshot-standard"/></a>
<br>
<br>
this is the command to do it
<br>
<pre class="code-standard">
docker login <your Container registry name>
</pre>
<br>
You are helped by the Container Registry Quick Start:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjno0mwC2XUxvSjgzQnxLu-fta2WKGrphwe0jUng11q8D87gMxAJvqLKrXKJRpgVK-DHf5Q9PH4n0Eb5IUecFo5vs02ZUhfUEO_aMosT8SZyBLw7X73ZsSnj0apTje1jKA8zug7elyy92YN/s1600/build-docker-image-deploy-WebApp-container+-+20+-+Azure+container+Registry+Quick+Start.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjno0mwC2XUxvSjgzQnxLu-fta2WKGrphwe0jUng11q8D87gMxAJvqLKrXKJRpgVK-DHf5Q9PH4n0Eb5IUecFo5vs02ZUhfUEO_aMosT8SZyBLw7X73ZsSnj0apTje1jKA8zug7elyy92YN/s1000/build-docker-image-deploy-WebApp-container+-+20+-+Azure+container+Registry+Quick+Start.png" class ="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0sskyF25JpzC4oa07quzmRA1e5EfFqZbQ_lPqwpbBQN8c9vM1ZLoIIc-SWJmLZY5E01DGF1C7NI3Bgx8gLNEKuMp5TlMZvHDaGeT9qqUZzTXqUcwF_9yZ4DisDK6iknUBXoRlt3WO_3JF/s1600/build-docker-image-deploy-WebApp-container+-+21+-+Azure+container+Registry+login.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0sskyF25JpzC4oa07quzmRA1e5EfFqZbQ_lPqwpbBQN8c9vM1ZLoIIc-SWJmLZY5E01DGF1C7NI3Bgx8gLNEKuMp5TlMZvHDaGeT9qqUZzTXqUcwF_9yZ4DisDK6iknUBXoRlt3WO_3JF/s1000/build-docker-image-deploy-WebApp-container+-+21+-+Azure+container+Registry+login.png" class ="screenshot-standard" /></a>
<br>
<br>
If you need the credentials you can find them here:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-J_LmjzqqBXrHxdjJ_z4VZwILXEIESvkS8iu8Y8YT0lZm0GrlbQ6sO-4fGZ9OeCPqL9IF9bs142oZ_K17SkIllPZUngMZUfAKGae2T33cHRVMi7ooSgC4_hkF7iIWda7-AWvcCFPphQwf/s1600/build-docker-image-deploy-WebApp-container+-+26+-+Azure+container+registry+credentials.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-J_LmjzqqBXrHxdjJ_z4VZwILXEIESvkS8iu8Y8YT0lZm0GrlbQ6sO-4fGZ9OeCPqL9IF9bs142oZ_K17SkIllPZUngMZUfAKGae2T33cHRVMi7ooSgC4_hkF7iIWda7-AWvcCFPphQwf/s1000/build-docker-image-deploy-WebApp-container+-+26+-+Azure+container+registry+credentials.png" class ="screenshot-standard" /></a>
<br>
<br>
Now, we have to define the container before pushing it:
<br>
<br>
<pre class="code-standard">
docker tag nodeapp <your Container registry name>.azurecr.io/nodeapp
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpB2roWf0avpLTMHQdw4QHoYry3KJ70JYqQknUpLE4h8-6AiVeOyUAoEF1KR2Zr_PpEczHmIeIF9NJ6txYDd3vSejuMMjWerRYzGKPq70I479iSbSlISBYzozVCx_6ELMmU2DDS1McoVn3/s1600/build-docker-image-deploy-WebApp-container+-+26+-+Azure+container+registry+container+tag+container+before+pushing.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpB2roWf0avpLTMHQdw4QHoYry3KJ70JYqQknUpLE4h8-6AiVeOyUAoEF1KR2Zr_PpEczHmIeIF9NJ6txYDd3vSejuMMjWerRYzGKPq70I479iSbSlISBYzozVCx_6ELMmU2DDS1McoVn3/s1000/build-docker-image-deploy-WebApp-container+-+26+-+Azure+container+registry+container+tag+container+before+pushing.png" class ="screenshot-standard" /></a>
<br>
<br>
then we start the push
<br>
<pre class="code-standard">
docker push <your Container registry name>.azurecr.io/nodeapp
</pre>
<br>
<br>
And it's amazing we are really seeing the container being pushed to Azure piece by piece:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNaKuXsp8VtryQHbv2I6JdMndraNOjke7VebSE2SwiJvNPyJzwH_M8krNBB2XBWhoRews1F8gm41j3_sVg_N4Ehg9sHDBMj9VTPMmKKU6ro2-FCQc1jisXnKxxNSg-f33xz7i0efvNjO_/s1600/build-docker-image-deploy-WebApp-container+-+27+-+Azure+container+registry+container+push.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNaKuXsp8VtryQHbv2I6JdMndraNOjke7VebSE2SwiJvNPyJzwH_M8krNBB2XBWhoRews1F8gm41j3_sVg_N4Ehg9sHDBMj9VTPMmKKU6ro2-FCQc1jisXnKxxNSg-f33xz7i0efvNjO_/s1000/build-docker-image-deploy-WebApp-container+-+27+-+Azure+container+registry+container+push.png" class ="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlmbF18g08XJoIcZ-jEXwZ2ftzRUpBAdEFqZ-5q6hXzUJ23AtyUaM7CQmbSAXlrgLob_m8lrKwSaHwW5a-307zlYjYB8hSvdbWRju0YbNZbHuiDNIWcLWJVkE7yjAP2Z0PWqY2PZU01RJO/s1600/build-docker-image-deploy-WebApp-container+-+28+-+Azure+container+registry+container+push.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlmbF18g08XJoIcZ-jEXwZ2ftzRUpBAdEFqZ-5q6hXzUJ23AtyUaM7CQmbSAXlrgLob_m8lrKwSaHwW5a-307zlYjYB8hSvdbWRju0YbNZbHuiDNIWcLWJVkE7yjAP2Z0PWqY2PZU01RJO/s1000/build-docker-image-deploy-WebApp-container+-+28+-+Azure+container+registry+container+push.png" class ="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLm3FG36KOWhWoUf4YLxwtYygsnDo5i91sPd13zwNy7zdE7leIdSPaTv1nXFbWhewsF9p_K76EHC0aD1rpM314JQlW0qlT8dekV88pUwFQ1ZPOkGR_nKjfSCwPrtpNZ73HhPNtyztYUefw/s1600/build-docker-image-deploy-WebApp-container+-+29+-+Azure+container+registry+container+push.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLm3FG36KOWhWoUf4YLxwtYygsnDo5i91sPd13zwNy7zdE7leIdSPaTv1nXFbWhewsF9p_K76EHC0aD1rpM314JQlW0qlT8dekV88pUwFQ1ZPOkGR_nKjfSCwPrtpNZ73HhPNtyztYUefw/s1000/build-docker-image-deploy-WebApp-container+-+29+-+Azure+container+registry+container+push.png" class ="screenshot-standard" /></a>
<br>
<br>
And finally it's done:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_7coQPabjXFteS3p6U9MUQqlGIlhPn0Oz9Nhb2PjroT94oNupnZsHEBWvSd6pt9xMwnnSAr_ZTxRtqlqnb0cPUuVHdrmjDg-EE8DsDo9u7vU13qdN7M3iIexla3VLsI9Pzlb2oYgd5ViL/s1600/build-docker-image-deploy-WebApp-container+-+30+-+Azure+container+registry+container+pushed.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_7coQPabjXFteS3p6U9MUQqlGIlhPn0Oz9Nhb2PjroT94oNupnZsHEBWvSd6pt9xMwnnSAr_ZTxRtqlqnb0cPUuVHdrmjDg-EE8DsDo9u7vU13qdN7M3iIexla3VLsI9Pzlb2oYgd5ViL/s1000/build-docker-image-deploy-WebApp-container+-+30+-+Azure+container+registry+container+pushed.png" class ="screenshot-standard" /></a>
<br>
<br>
And we can see the push result in Azure Container registry:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjohoJe5cFrGPQNIOvYOTd7nR1kDVDnQz50P0K3bnkQUMDhEuzB4vwFB64upwNzyB6XbJG-tDyUE_C2nSZMfI4u7Dao4F-rE-1Yjc3xEssUv8b-qFwiICostDjoH94wCjws_kgCAVebvaPT/s1600/build-docker-image-deploy-WebApp-container+-+31+-+Azure+container+registry+repository+created.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjohoJe5cFrGPQNIOvYOTd7nR1kDVDnQz50P0K3bnkQUMDhEuzB4vwFB64upwNzyB6XbJG-tDyUE_C2nSZMfI4u7Dao4F-rE-1Yjc3xEssUv8b-qFwiICostDjoH94wCjws_kgCAVebvaPT/s1000/build-docker-image-deploy-WebApp-container+-+31+-+Azure+container+registry+repository+created.png" class ="screenshot-standard" /></a>
<br>
<br>
<h2>Deploying the container to a Web App for Containers</h2>
Now if we want our container to run and display our API we can, for example, deploy it to an Azure Web App for Containers
<br>
<br>
For doing so, navigate to the container and open the latest push features by clicking on the dots and select "Deploy to web app":
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD2k1beo4JVpwe4Mnz_12Q3uRQvPaCuyd0GA0DZ3xE2dbyhJjFGkd4wy3d_-UavOFvphwoyG2rkT3GkHiWapDDG-RFdvCO21onxliEQIYo7bLcSeArW_K8pl8rZB3SPW4tpQMjz1FxhQMJ/s1600/build-docker-image-deploy-WebApp-container+-+32+-+Azure+container+registry+deployment+settings.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD2k1beo4JVpwe4Mnz_12Q3uRQvPaCuyd0GA0DZ3xE2dbyhJjFGkd4wy3d_-UavOFvphwoyG2rkT3GkHiWapDDG-RFdvCO21onxliEQIYo7bLcSeArW_K8pl8rZB3SPW4tpQMjz1FxhQMJ/s1000/build-docker-image-deploy-WebApp-container+-+32+-+Azure+container+registry+deployment+settings.png" class ="screenshot-standard" /></a>
<br>
<br>
Name your container, chose subscription and resource group, select a service plan. I have one for Linux and had to locate it in North Europe because it is one of the region available for the Linux Web App for containers and we can have only one Free Plan for Linux Web App for Containers. So no choice for me.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghMD13azqH_OFmqxno5HgEn_mT_Aysj9QqdUGR05AK8qo5QIrt8ZFdmiVIL36B86L5g-B3RnEY-uhA1Q1dujlom3w3s_KXnlcT2nHOziVGvKblsEh1rLhk3Uhlm6pgP5kVy1P8terfzwY-/s1600/build-docker-image-deploy-WebApp-container+-+33+-+Azure+container+registry+deployment+set.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghMD13azqH_OFmqxno5HgEn_mT_Aysj9QqdUGR05AK8qo5QIrt8ZFdmiVIL36B86L5g-B3RnEY-uhA1Q1dujlom3w3s_KXnlcT2nHOziVGvKblsEh1rLhk3Uhlm6pgP5kVy1P8terfzwY-/s1000/build-docker-image-deploy-WebApp-container+-+33+-+Azure+container+registry+deployment+set.png" class ="screenshot-standard" /></a>
<br>
<br>
After having clicked on the create button, we can check the deployment setps:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMn3VNHeY7LUuVfwhxeGZJO4GvFmnrV3od5voz0rTpUWTcvnqDWy3YUDy-i43joVRk7RBZ5gWOfOri6t2s2-AUuyHDUQqqGpMYyldNQSvsvusCoEH6f_7yFMRWn28wVQH7bvTEljEpmpCT/s1600/build-docker-image-deploy-WebApp-container+-+44+-+web+app+creation.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMn3VNHeY7LUuVfwhxeGZJO4GvFmnrV3od5voz0rTpUWTcvnqDWy3YUDy-i43joVRk7RBZ5gWOfOri6t2s2-AUuyHDUQqqGpMYyldNQSvsvusCoEH6f_7yFMRWn28wVQH7bvTEljEpmpCT/s1000/build-docker-image-deploy-WebApp-container+-+44+-+web+app+creation.png" class ="screenshot-standard" /></a>
<br>
<br>
And finally it's deployed
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGoWKV6jL94v1FShs01HrSkxPYLWJO3-WFOpY0Dtof7twMpmC9gQ9oXLZJWTDt_HpZD0HQUK5JAVvQrQf3BDPXJvCcIxMNunIjAIm9ISuWVuWfPL2MniWDOJJizWQ8aJA370qvqeSL_U5/s1600/build-docker-image-deploy-WebApp-container+-+46+-+web+app+created.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGoWKV6jL94v1FShs01HrSkxPYLWJO3-WFOpY0Dtof7twMpmC9gQ9oXLZJWTDt_HpZD0HQUK5JAVvQrQf3BDPXJvCcIxMNunIjAIm9ISuWVuWfPL2MniWDOJJizWQ8aJA370qvqeSL_U5/s1000/build-docker-image-deploy-WebApp-container+-+46+-+web+app+created.png" class ="screenshot-standard" /></a>
<br>
<br>
We can go to the Overview page of the Web App for Containers where our Linux Alpine container with the Node.js API is deployed:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmG-6vsZ_zNhl3Y2AOYN24Q3f1kQMzYP1NU2CvNknsB-zI1vtny_CJb68gzhwb2SRHXVwznhqv0kYBNsVdowtEFNb4epcsHOv78zyJmHocpGn71ZMo3ekO8kygunDgQfCMXm10oq97xKQ-/s1600/build-docker-image-deploy-WebApp-container+-+48+-+web+app+container+overview.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmG-6vsZ_zNhl3Y2AOYN24Q3f1kQMzYP1NU2CvNknsB-zI1vtny_CJb68gzhwb2SRHXVwznhqv0kYBNsVdowtEFNb4epcsHOv78zyJmHocpGn71ZMo3ekO8kygunDgQfCMXm10oq97xKQ-/s1000/build-docker-image-deploy-WebApp-container+-+48+-+web+app+container+overview.png" class ="screenshot-standard" /></a>
<br>
<br>
And we can test it works properly by clicking on the Url:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmdDOFYHOTQkxnGiubUD9k3LzgflTBRZ3dT6zWbUg88mt5KNn99N_T3dnNXeSOiEYPQKZCGJRrkYOCzIppyaqy-vmsZymL3noqI7egVW199nipvFGoGH7spmfXuoj9qWexSjvO84IGSqMz/s1600/build-docker-image-deploy-WebApp-container+-+49+-+web+app+container+testing.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmdDOFYHOTQkxnGiubUD9k3LzgflTBRZ3dT6zWbUg88mt5KNn99N_T3dnNXeSOiEYPQKZCGJRrkYOCzIppyaqy-vmsZymL3noqI7egVW199nipvFGoGH7spmfXuoj9qWexSjvO84IGSqMz/s1000/build-docker-image-deploy-WebApp-container+-+49+-+web+app+container+testing.png" class ="screenshot-standard"/></a>
<br>
<br>
Well done!
<br>
<br>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-46577388347111306542019-09-12T12:06:00.001+02:002019-09-12T18:15:27.517+02:00Troubleshoot Docker registry login timeout issue for Docker Toolbox<div class="h2-paragraph">
<h2>topic</h2>
Solve error:
<br>
<b>docker registry login net/http: request canceled while waiting for connection (Client.Timeout exceeded...</b>
<br>
especially
<br>
<b>docker azure registry login net/http: request canceled while waiting for connection (Client.Timeout exceeded..</b>
<br>
when wanting to log to a Docker registry while using the Docker tool box.
<h2>Introduction</h2>
If you want to work with Docker using a Windows 10 OS, Home version, you won't be allowed by the installation program to install Docker desktop. Docker desktop needs Hyper V and although Hyper V is now available even on Windows 10 Home, the Docker desktop installation program still checks only the OS version. If it doesn't find a Pro or an Enterprise version on your computer, it stops installation.
<br>
Fortunately you can performs the main Docker tasks using Docker tool box.
<h2>Error reason</h2>
The "Client.Timeout exceeded" issue while attempting to login to a Docker registry is due to a bad network configuration of your Docker Toolbox. When installing Docker Toolbox a default Virtual Box VM is also installed to your computer with 2 networks adapters. It is located at:
drive\user\.docker\machine\machines\default
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnWW5w9hna7yn4OK4QCnxK-X22k3PshA2SftZza5Gz8ozt3fYRxaHYssZwmMhDs5e1Uw4vX6hodPpDj_By72B4TTyouhWftPXM_nTDY4Ugsr4hCWscD3OG6L5c-9H_gLsgIVf9gzNF3o_K/s1600/docker-registry-login-timeout-issue-toolbox-00+-+defautl+vm+harddrive++%25282%2529.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnWW5w9hna7yn4OK4QCnxK-X22k3PshA2SftZza5Gz8ozt3fYRxaHYssZwmMhDs5e1Uw4vX6hodPpDj_By72B4TTyouhWftPXM_nTDY4Ugsr4hCWscD3OG6L5c-9H_gLsgIVf9gzNF3o_K/s1000/docker-registry-login-timeout-issue-toolbox-00+-+defautl+vm+harddrive++%25282%2529.png" class="screenshot-standard" /></a>
<br>
<br>
you can open it with Oracle Virtual Box that is also installed with the Docker Toolbox. If you open Settings and Network you will see the 2 adapters.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkFFVFTSWHwK8yqz1ynkD51EDeieJf9OpoM4xa85TgRytgcilpMO6-X36AR0Z5Bd496MxRJMxCQY_BHs6lg4o76iQk20n2__L0kzGWfmMaP9Gv9CkFA__R_SzqB4je0N_S_9vxkaLKgm_/s1600/docker-registry-login-timeout-issue-toolbox-+01+-+defautl+vm+network+adapters.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkFFVFTSWHwK8yqz1ynkD51EDeieJf9OpoM4xa85TgRytgcilpMO6-X36AR0Z5Bd496MxRJMxCQY_BHs6lg4o76iQk20n2__L0kzGWfmMaP9Gv9CkFA__R_SzqB4je0N_S_9vxkaLKgm_/s1600/docker-registry-login-timeout-issue-toolbox-+01+-+defautl+vm+network+adapters.png" class="screenshot-standard" /></a>
<br>
<br>
<span style="color:red">Warning:</span>
If you play with the virtual box and close it, you will close also the connection to your running containers. It is like disable the network adapter that allows you to connect to the running containers and test them locally. If you have this issue, close the docker Toolbox and restart it. A new connection and IP address will be reallocated:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimocRslt18a_Wk8KP9zPU7cyw6wGXCNSfZ1GJASpBzKVA-pgiM7jou9x7qW6IddhLVItdpE-EbtN7loa8sQ9EdY8Q6__uvTrg1oHO90C_0pQr3Zm0DICgILKIU-RXMas6bAC3gPu5FMP7V/s1600/docker-registry-login-timeout-issue-toolbox-+06+-+restarting+docker+quickstart+terminal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimocRslt18a_Wk8KP9zPU7cyw6wGXCNSfZ1GJASpBzKVA-pgiM7jou9x7qW6IddhLVItdpE-EbtN7loa8sQ9EdY8Q6__uvTrg1oHO90C_0pQr3Zm0DICgILKIU-RXMas6bAC3gPu5FMP7V/s1000/docker-registry-login-timeout-issue-toolbox-+06+-+restarting+docker+quickstart+terminal.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjut_tb4n7GCcufWO49o__kPEFBBELX-SasEmprKN5JEpr2U9JU_EIGaWu5oljYgCh2dgFmNtqD0wBOAK83yarvQLiZxDtfvu4uuS3USxFwp5dvsQCZtrR6pYu5f70zA0nttzARpfh_yCwx/s1600/docker-registry-login-timeout-issue-toolbox-+07+-+restarting+docker+quickstart+terminal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjut_tb4n7GCcufWO49o__kPEFBBELX-SasEmprKN5JEpr2U9JU_EIGaWu5oljYgCh2dgFmNtqD0wBOAK83yarvQLiZxDtfvu4uuS3USxFwp5dvsQCZtrR6pYu5f70zA0nttzARpfh_yCwx/s1000/docker-registry-login-timeout-issue-toolbox-+07+-+restarting+docker+quickstart+terminal.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggfA2o7lT2oWVRvwgf7mvBSsTo7ufkr2eeFmwY5qjW44LgUN0230rMfNeT-qbcjoeWdE8-8ZDusP6fcmWTc77aOehyF8qRyWmltHBXp0yU6d4RONYo-_jtm1ttZtHKYLbeYagDiHcVQkcb/s1600/docker-registry-login-timeout-issue-toolbox-+08+-+restarting+docker+quickstart+terminal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggfA2o7lT2oWVRvwgf7mvBSsTo7ufkr2eeFmwY5qjW44LgUN0230rMfNeT-qbcjoeWdE8-8ZDusP6fcmWTc77aOehyF8qRyWmltHBXp0yU6d4RONYo-_jtm1ttZtHKYLbeYagDiHcVQkcb/s1000/docker-registry-login-timeout-issue-toolbox-+08+-+restarting+docker+quickstart+terminal.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg8PiYHhr7xNWGEB0mvvKPOk3tfyeCediD3igPoeEPAlSLKIkMO3ugc4NJSAFH3zis-dkW6VLiM-LaE-Az7pWjAOSrhiTyrneO05__hAb4vzTb2exnRKDvZN9K9NXVZ5qpbuHzoRSokzXg/s1600/docker-registry-login-timeout-issue-toolbox-+09+-+restarting+docker+quickstart+terminal+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg8PiYHhr7xNWGEB0mvvKPOk3tfyeCediD3igPoeEPAlSLKIkMO3ugc4NJSAFH3zis-dkW6VLiM-LaE-Az7pWjAOSrhiTyrneO05__hAb4vzTb2exnRKDvZN9K9NXVZ5qpbuHzoRSokzXg/s1000/docker-registry-login-timeout-issue-toolbox-+09+-+restarting+docker+quickstart+terminal+.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>Troubleshouting the issue</h2>
For troubleshooting the timeout issue you have to configure the Virtual Box Network Adapters.
<br>
<br>
Open the settings of Windows 10
<br>
Go to Network & Internet settings:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU0WgNWZ54Z-Z1otObQVEJA9IrEHtDOKy2OyNvB6Xd24PWySfqftmNKKcsEgr5Hv49W1DKmh-weIlEqf56kDatwhKy18UpSYGh-MK-oLXKuwK7ZbbwxdrUJdSrdS6x8X7I3deDxE9JK5sT/s1600/docker-registry-login-timeout-issue-toolbox-+02+-+windows+10+settings+-+network+settings.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU0WgNWZ54Z-Z1otObQVEJA9IrEHtDOKy2OyNvB6Xd24PWySfqftmNKKcsEgr5Hv49W1DKmh-weIlEqf56kDatwhKy18UpSYGh-MK-oLXKuwK7ZbbwxdrUJdSrdS6x8X7I3deDxE9JK5sT/s1600/docker-registry-login-timeout-issue-toolbox-+02+-+windows+10+settings+-+network+settings.png" class="screenshot-large" /></a>
<br>
<br>
then, Change adapter options
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGg-OCXbjlWYpDIaqxnZxjeFs2nBoTrysgWOTFwodQnshypjvMnEzAGP68nxgnMJcIaDc1Y2Lqfhg3mYVE6kRg2wdP4LT6b4jV3HEM3ZXd6hVrmaYSTyqiPSUaRqlraQL0YlIeGlPI8kxN/s1600/docker-registry-login-timeout-issue-toolbox-+03+-+windows+10+settings+-+network+settings.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGg-OCXbjlWYpDIaqxnZxjeFs2nBoTrysgWOTFwodQnshypjvMnEzAGP68nxgnMJcIaDc1Y2Lqfhg3mYVE6kRg2wdP4LT6b4jV3HEM3ZXd6hVrmaYSTyqiPSUaRqlraQL0YlIeGlPI8kxN/s1600/docker-registry-login-timeout-issue-toolbox-+03+-+windows+10+settings+-+network+settings.png" class="screenshot-large" /></a>
<br>
<br>
then double click on <b>VirtualBox Host-Only Network</b>
<br>Properties
<br>Select Internet Protocol Version 4
<br>Open properties
<br>Set the DNS to 8 8 8 8
<br>
<br>
It should fix the timeout issue.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZDZhdFH1xcoaG1-hYE_EMk3qFBt6nztWh6mS9Ce5jcbHHCVCLEsKciEbJrRPdJxOmJRQxfcbiux7GswRRe3xIzGiOuSWfHGQDtU87JbltL19-OsdRCICDCnD-sGcSbOphjpbBCPEn2YM_/s1600/docker-registry-login-timeout-issue-toolbox-+04+-+windows+10+virtual+box+host+ipv4+dns.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZDZhdFH1xcoaG1-hYE_EMk3qFBt6nztWh6mS9Ce5jcbHHCVCLEsKciEbJrRPdJxOmJRQxfcbiux7GswRRe3xIzGiOuSWfHGQDtU87JbltL19-OsdRCICDCnD-sGcSbOphjpbBCPEn2YM_/s1000/docker-registry-login-timeout-issue-toolbox-+04+-+windows+10+virtual+box+host+ipv4+dns.png" class="screenshot-standard" /></a>
<br>
<br>
<b>do the same for VirtualBox Host-Only Network # 2</b>
<br>
<br>
It seems that it has solved also connection troubles for the Docker Extension of Visual Studio Code.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsvrRv-MmnkZyPPVX2Ls1bwo1B8p0WvI-ylB-bE9njZ-KQLDhLrS2udB1c4Qqs-i_nR7CG7dArKKxoryMFQd3p2bPlutcljle2kDayzjdIfFENP1C8rf65uyETtVzjFfD9QxuqtdKhCZmR/s1600/docker-registry-login-timeout-issue-toolbox-+05+-+VS+Code+docker+extension+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsvrRv-MmnkZyPPVX2Ls1bwo1B8p0WvI-ylB-bE9njZ-KQLDhLrS2udB1c4Qqs-i_nR7CG7dArKKxoryMFQd3p2bPlutcljle2kDayzjdIfFENP1C8rf65uyETtVzjFfD9QxuqtdKhCZmR/s1600/docker-registry-login-timeout-issue-toolbox-+05+-+VS+Code+docker+extension+.png" class="screenshot-standard" /></a>
<br>
<br>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-37714704701948659322019-09-11T14:33:00.002+02:002019-09-11T15:24:55.345+02:00Deploy a Flask Restplus API to an Azure Linux Web App<div class="h2-paragraph">
<h2>Topic:</h2>
Deploy a python Flask Restplus API to an Azure Linux Web App (code available in my github repo: <a href="https://github.com/MarcCharmois/app-service-Linux-API-Python">app-service-Linux-API-Python</a> )
<h2>Tutorial</h2>
I will publish soon :
<ul>
<li>the steps and screenshots to configure your local (windows) environment for Python</li>
<li>the deployment steps and screenshots</li>
</ul>
<span class="highlight">the Web App creation steps and screenshots are the same than those of the previous post</span>
<br>
The deployment steps are quite the same excepted that you clone the code from the git repo and add a remote to the Azure Web App.
<h2>Deployment steps</h2>
roughly:
<ul>
<li>Create an Azure Linux Web App (App service on Linux)</li>
<li>Go to deployment center and chose : Git local, App Service build engine</li>
<li>clone the code of my repo: <a href="https://github.com/MarcCharmois/app-service-Linux-API-Python">app-service-Linux-API-Python</a></li>
<li>Add the WebApp git url of the deployment center as a remote</li>
<li>Push the code to the Web App. When asked for credentials go to FTP/Credentials an copy Username and Password. The Username to use begins by the $, don't take the domain.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC5rKSSnPlwbcIsTVJtJhWh2eeIQp5XtXg58ybro5c6c3IoXrkS3vvEV-HoHyzsCbv7m8SRJ97tADABYhxRD3iT2djH0Hl2Ro0pyCuplq1Lp6PTe1p7_JdTmXDW6lwOwzKuNxsAxe8fors/s1600/Azure-WebApp-Linux-FalskRestplus-API+-+100+-+azure+deployment+center+-+Web+App+deployment+credentials.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC5rKSSnPlwbcIsTVJtJhWh2eeIQp5XtXg58ybro5c6c3IoXrkS3vvEV-HoHyzsCbv7m8SRJ97tADABYhxRD3iT2djH0Hl2Ro0pyCuplq1Lp6PTe1p7_JdTmXDW6lwOwzKuNxsAxe8fors/s1600/Azure-WebApp-Linux-FalskRestplus-API+-+100+-+azure+deployment+center+-+Web+App+deployment+credentials.png" class="screenshot-large" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgirs8rhXzGueiLNOKWTvGaD5LbzqL4a3gjAohK7pSf_FKIZSAC44rU-jqNLl3mOwS5T_KNyz5kADNn673rLnMR8MWEc_9KUe_kt5IfC2adzdu_8h4yOPlpqTEFPUrWi89UBT3LFhrGpTLG/s1000/azure-web-app-linux-node.js+-+43+-+entering+credentials+after+git+push.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgirs8rhXzGueiLNOKWTvGaD5LbzqL4a3gjAohK7pSf_FKIZSAC44rU-jqNLl3mOwS5T_KNyz5kADNn673rLnMR8MWEc_9KUe_kt5IfC2adzdu_8h4yOPlpqTEFPUrWi89UBT3LFhrGpTLG/s1000/azure-web-app-linux-node.js+-+43+-+entering+credentials+after+git+push.png" class="screenshot-large" /></a>
</li>
</ul>
<h2>After deployment</h2>
this is the result after deployment:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0zIBe-RWBrt-rjkp4GGitofykHuK7xNYW4-NWr-s1q_Rxrjc4ahI0sNIG-gCK-lXC3tXz0wjDKGrYdQCPBqc2J9VC4MqKfY7l44yd1BRIFtQp6NXzwBYS0ikpGNZ63JTWSv2ivcSBxn2-/s1600/Azure-WebApp-Linux-FalskRestplus-API+-+100+-+azure+deployment+center+-+api+deployed.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0zIBe-RWBrt-rjkp4GGitofykHuK7xNYW4-NWr-s1q_Rxrjc4ahI0sNIG-gCK-lXC3tXz0wjDKGrYdQCPBqc2J9VC4MqKfY7l44yd1BRIFtQp6NXzwBYS0ikpGNZ63JTWSv2ivcSBxn2-/s1600/Azure-WebApp-Linux-FalskRestplus-API+-+100+-+azure+deployment+center+-+api+deployed.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3KkKGXH6fpRBXKbzhwuBTNBDAOad6vwWolxN6MmbXoUvNpP9Ci4pKtAf8j3zhp_8uxdOfe_rVEkq0vrsUEYN082pn3wzyh8PUchRdmFOTAxGe1TOXKHhrCFUw4gTHJZIS3EK5js1x1bpO/s1600/Azure-WebApp-Linux-FalskRestplus-API.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3KkKGXH6fpRBXKbzhwuBTNBDAOad6vwWolxN6MmbXoUvNpP9Ci4pKtAf8j3zhp_8uxdOfe_rVEkq0vrsUEYN082pn3wzyh8PUchRdmFOTAxGe1TOXKHhrCFUw4gTHJZIS3EK5js1x1bpO/s1600/Azure-WebApp-Linux-FalskRestplus-API.png" class="screenshot-standard" /></a>
<br>
<br>
It is online with anonymous access, you can play with it:
<br>
<br>
<a href="https://linux-python-api.azurewebsites.net/">try the Flask Restplus features</a>
<br>
<br>
Enjoy!
<br>
<br>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-8931296384345883052019-09-09T15:33:00.004+02:002019-09-11T16:36:22.768+02:00Build a Node.js application and deploy it (git push) to an Azure Linux Web App (Azure App Service on Linux)<div class="h2-paragraph">
<h2>
Topic </h2>
This post shows how to create a Node.js Express application and deploy it to an Azure Linux Web App using a git push.
<br />
<h2>
Prerequistes</h2>
You must have:
<br />
<ul>
<li><a href="https://nodejs.org/en/">Node.js</a></li>
<li><a href="https://git-scm.com/downloads">Git</a></li>
</ul>
<h2>
Creating the Azure Linux Web App via the portal</h2>
Sign-in to Azure Portal and click on "Create a resource" (1), then Web App (2).
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU1qcEmGf2UMBS8TufZxUpO0rjg3Xh-uG_HI6wt8d_iNkZqUxHFNTbjbGqFjSEKpGXyht22hEQ0MN4wjSNlZn4iaPaYyUjfYft7bNMmdyO-iqklG7aiKJXIolC8S7uebD3VDyW0TlH-i2H/s1600/azure-web-app-linux-node.js+-+04+-++create+node.js++linux+web+app+-+create+new+web+app.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU1qcEmGf2UMBS8TufZxUpO0rjg3Xh-uG_HI6wt8d_iNkZqUxHFNTbjbGqFjSEKpGXyht22hEQ0MN4wjSNlZn4iaPaYyUjfYft7bNMmdyO-iqklG7aiKJXIolC8S7uebD3VDyW0TlH-i2H/s1000/azure-web-app-linux-node.js+-+04+-++create+node.js++linux+web+app+-+create+new+web+app.png" /></a>
<br />
<br />
Chose your Subscription, your Resource Group, your Azure Web App name, and let the other values unchanged because by default the Web App creation pane is configured for "Code" and "Linux".
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNAn5HoPYzp3y6-PCr1NS-2bYskfcXw4Q6EsRjnO-QCmgb8isJZ8ZrwH3INEzXZ5Rf3sgzBkjrYOpy-R5SMeaiShXr8Ia8RULO51E413Y1Dm7KlJ-9FzxJpbBsM2I7MLyvBdYMhAesLmcb/s1600/azure-web-app-linux-node.js+-+05+-++create+node.js++linux+web+app+-+chose+stack+node.js.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNAn5HoPYzp3y6-PCr1NS-2bYskfcXw4Q6EsRjnO-QCmgb8isJZ8ZrwH3INEzXZ5Rf3sgzBkjrYOpy-R5SMeaiShXr8Ia8RULO51E413Y1Dm7KlJ-9FzxJpbBsM2I7MLyvBdYMhAesLmcb/s1000/azure-web-app-linux-node.js+-+05+-++create+node.js++linux+web+app+-+chose+stack+node.js.png" /></a>
<br />
<br />
Then, chose your stack. I took Node 10.14 but it seems it's better to take Node LTS (newer).
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuKqtDByQCm3qDbUkwvM6C-Map7cOpTmoy01bIAa5gUAQcMhl0FykfrcdWeXYaAq8cHwia1OcCDp-64_u5pRlXLervAqdBOB55NFLSA_9O0RVz-Pxtmi6JpIMSRs_7-6MFqrKq4pvlbX0A/s1600/azure-web-app-linux-node.js+-+06+-++create+node.js++linux+web+app+-+chose+stack+node.js.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuKqtDByQCm3qDbUkwvM6C-Map7cOpTmoy01bIAa5gUAQcMhl0FykfrcdWeXYaAq8cHwia1OcCDp-64_u5pRlXLervAqdBOB55NFLSA_9O0RVz-Pxtmi6JpIMSRs_7-6MFqrKq4pvlbX0A/s1000/azure-web-app-linux-node.js+-+06+-++create+node.js++linux+web+app+-+chose+stack+node.js.png" /></a>
<br />
<br />
Then, chose your App Service Plan. You can have just one Free App Service Plan for Linux Azure Web App. As I have already, previously, created an Azure Web App for containers based on Linux and it is only available in North Europe (not yet in France), I had to based my free Linux sService Plan on North Europe. So for this new Linux Azure Web App I had no other choice than chosing North Europe as the region, in order to take benefits of the free App Service Plan for Linux.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5RQ9Y_7N0MzbnAFp5HJq1rYiPooDjxtyJMv1HBPY12IRKtkxbUG2_SbDZv59anpcitAlk0km31xM2oY2opqXHh8I-0f51Qn3VgThjbZ4S_4bGQv_rfI6rcX05wRonKzK62gVlcbmP8B22/s1600/azure-web-app-linux-node.js+-+08+-++create+node.js++linux+web+app++-+chose+app+service+plan+free+linked+to+region.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5RQ9Y_7N0MzbnAFp5HJq1rYiPooDjxtyJMv1HBPY12IRKtkxbUG2_SbDZv59anpcitAlk0km31xM2oY2opqXHh8I-0f51Qn3VgThjbZ4S_4bGQv_rfI6rcX05wRonKzK62gVlcbmP8B22/s1000/azure-web-app-linux-node.js+-+08+-++create+node.js++linux+web+app++-+chose+app+service+plan+free+linked+to+region.png" /></a>
<br />
<br />
Review and create page summarizes your choices before creating the Azure Web App. Then, click on Create.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaRKW7DlHqrm60jsYNhmBuJC1mbEJ3mf74IK-eQFbs4eF-NefRn1QxCdquKVNZhsm8LMJ1HmAk1_7HMd4wIFg57NR97RNvuTSW3FkQVOwif_3Pk09nVMJAUKj_op-9tD328xDHblGsN1Ah/s1600/azure-web-app-linux-node.js+-+12+-++create+node.js++linux+web+app++-+review+and+create.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaRKW7DlHqrm60jsYNhmBuJC1mbEJ3mf74IK-eQFbs4eF-NefRn1QxCdquKVNZhsm8LMJ1HmAk1_7HMd4wIFg57NR97RNvuTSW3FkQVOwif_3Pk09nVMJAUKj_op-9tD328xDHblGsN1Ah/s1000/azure-web-app-linux-node.js+-+12+-++create+node.js++linux+web+app++-+review+and+create.png" /></a>
<br />
<br />
You can then follow the steps of the Azure Web App creation.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQP00x2rIq4Jjn73PlMR5NX9HdLMK5PpIoqqEtyygNxnl5c4ZgBoVtzVM36IU6vChmoXscJkFTKrs_1P3_CBJK8QJtMr0reGtineRWeUXgFoQ7lcrUKg0hrVw3xOYj4pVsCXvV8fXHzR0E/s1600/azure-web-app-linux-node.js+-+14+-++create+node.js++linux+web+app++-+deployment+underway.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQP00x2rIq4Jjn73PlMR5NX9HdLMK5PpIoqqEtyygNxnl5c4ZgBoVtzVM36IU6vChmoXscJkFTKrs_1P3_CBJK8QJtMr0reGtineRWeUXgFoQ7lcrUKg0hrVw3xOYj4pVsCXvV8fXHzR0E/s1000/azure-web-app-linux-node.js+-+14+-++create+node.js++linux+web+app++-+deployment+underway.png" /></a>
<br />
<br />
Until it's complete.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHy3CasgECK_Bbwgk0FqIcvMdq9dplSwQsNrsdqiQ5PeJ6i9Q0oQwBHfQDTQzQXqiav4t6UoxM0lKcK7YbT9RF5uJMgfd5fdLnZGUVmR2eqYFygkFVd5id23wwZtTyxYQJXYhHptMA-HHC/s1600/azure-web-app-linux-node.js+-+16+-+create+node.js++linux+web+app+-+deployment+complete.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHy3CasgECK_Bbwgk0FqIcvMdq9dplSwQsNrsdqiQ5PeJ6i9Q0oQwBHfQDTQzQXqiav4t6UoxM0lKcK7YbT9RF5uJMgfd5fdLnZGUVmR2eqYFygkFVd5id23wwZtTyxYQJXYhHptMA-HHC/s1000/azure-web-app-linux-node.js+-+16+-+create+node.js++linux+web+app+-+deployment+complete.png" /></a>
<br />
<br />
Go then to the "Overview" page of your brand new Azure Linux Web App, And click on the Azure Web App Url to test it:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMtc6AOSwYOK1xVztp5YWW-O2X0PIkzKN-pDez-0Hpxk3S1sDrCa3ADdAG-6HPeDUqjcnbgUMIm5q9VecbjAT_M0LYgaL3iT66v7P_BHw6_U2Mv-tzUG3rpqiVMMk-gpXjSeLXXHB5yEut/s1600/azure-web-app-linux-node.js+-+18+-+web+app+overview.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMtc6AOSwYOK1xVztp5YWW-O2X0PIkzKN-pDez-0Hpxk3S1sDrCa3ADdAG-6HPeDUqjcnbgUMIm5q9VecbjAT_M0LYgaL3iT66v7P_BHw6_U2Mv-tzUG3rpqiVMMk-gpXjSeLXXHB5yEut/s1000/azure-web-app-linux-node.js+-+18+-+web+app+overview.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiFYUoeuu06-i_KQn_atl9tWvkvoVwqK3HQz00Lt-pIC6h4g77SJ_bXqz65QpKn6UVn7MRpTKXHdYbd7W3BfglxDiZkjNQ8ZxFqDRqLAqVWeyDu3RW-10Dxkt_Kd7Lf03zAIE_0zmr7SzT/s1600/azure-web-app-linux-node.js+-+20+-+testing+the+web+app.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiFYUoeuu06-i_KQn_atl9tWvkvoVwqK3HQz00Lt-pIC6h4g77SJ_bXqz65QpKn6UVn7MRpTKXHdYbd7W3BfglxDiZkjNQ8ZxFqDRqLAqVWeyDu3RW-10Dxkt_Kd7Lf03zAIE_0zmr7SzT/s1000/azure-web-app-linux-node.js+-+20+-+testing+the+web+app.png" /></a>
<br />
<br />
<h2>
Exploring the Azure Linux Web App with SSH tool</h2>
Locate the SSH tool in the development tools section of your Web App menu and open it.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiktdyE2GmKsbJTIiwsJke7tba7q_LkAn-piSpecVwv7YhMd0cd1FiAB2YeIoFVRUs6eIL3TrdORZHJggjuRNbrzys1GJdgQpHrO0xmNiVSgZ1aMqw8HolvBP0ZtC1D7nsV1YJJsuNSoc-B/s1600/azure-web-app-linux-node.js+-+22.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiktdyE2GmKsbJTIiwsJke7tba7q_LkAn-piSpecVwv7YhMd0cd1FiAB2YeIoFVRUs6eIL3TrdORZHJggjuRNbrzys1GJdgQpHrO0xmNiVSgZ1aMqw8HolvBP0ZtC1D7nsV1YJJsuNSoc-B/s1000/azure-web-app-linux-node.js+-+22.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcfjbVW4lkKCoohJ6QoDFd2e2I_sM7OERT3tfhshr-wuJCSchzB3iyR5BUzjuX-891tejROJOqr3DBucEvOiJ18BaJXExQPa9Lgf0FjyaAHuqF84lNErlPEGMuXcsw6XNPjLOHTk9SH4g5/s1600/azure-web-app-linux-node.js+-+24.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcfjbVW4lkKCoohJ6QoDFd2e2I_sM7OERT3tfhshr-wuJCSchzB3iyR5BUzjuX-891tejROJOqr3DBucEvOiJ18BaJXExQPa9Lgf0FjyaAHuqF84lNErlPEGMuXcsw6XNPjLOHTk9SH4g5/s1000/azure-web-app-linux-node.js+-+24.png" /></a>
<br />
<br />
You, then, can use the "cd" command to navigate through the folders hierarchy and "ls" to list their content. ("dir" works also).
You notice that in wwwroot folder, we only have the hostingstart.html page that displayed previously when testing the Azure Linux Web App.
<br />
<br />
<h2>
Creating the Node.js Express Application</h2>
Open a command prompt, navigate to your development folder, and install Express Generator by typing:
<br />
<pre class="code-standard" style="padding-left: 15px;">npm install -g express-generator
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGmRxud8Mat69umoNjp35AV23wg5OQX3Ys1FpI_AoRqDOM9DfBb3RMMm_-9xKlcFTXbkt-gulwC4ck1UsE8s4MtlT6ol_fPlXCBzlhcymvKb4WeTu9iHuyWYEsflWRsvS5k1PG850fPFkt/s1600/azure-web-app-linux-node.js+-+26+-+installing+Express+generator.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGmRxud8Mat69umoNjp35AV23wg5OQX3Ys1FpI_AoRqDOM9DfBb3RMMm_-9xKlcFTXbkt-gulwC4ck1UsE8s4MtlT6ol_fPlXCBzlhcymvKb4WeTu9iHuyWYEsflWRsvS5k1PG850fPFkt/s1000/azure-web-app-linux-node.js+-+26+-+installing+Express+generator.png" /></a>
<br />
<br />
Then, create locally your Node.js Express application by typing:
<br />
<pre class="code-standard" style="padding-left: 15px;">express WebApp-Linux-Node --view pug --git
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTMM73Wc_yk49CkXaCwVvWXdWI9lpzhsoBZdQhuW-QhGSWbrcEldNSiC8gIUZ9PDLJrEhWwthozt2nABYcn2bj2A17uOzaNpCNJBFppc-dz6sduYF-C7FXMWVpjP45GLUiQ-sbXzbFdjOl/s1600/azure-web-app-linux-node.js+-+27+-+creating+the+Web+App+code+with+Node+Express+Generator+1.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTMM73Wc_yk49CkXaCwVvWXdWI9lpzhsoBZdQhuW-QhGSWbrcEldNSiC8gIUZ9PDLJrEhWwthozt2nABYcn2bj2A17uOzaNpCNJBFppc-dz6sduYF-C7FXMWVpjP45GLUiQ-sbXzbFdjOl/s1000/azure-web-app-linux-node.js+-+27+-+creating+the+Web+App+code+with+Node+Express+Generator+1.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3nsURurQJ5JXO-QgtL0tzO0bQ3KJmiA-dcfiJuPyi4VrA0uswsRJ64otAbZAoyPZ1uA9z5R95BlNZVUW2-QfF6lRhkyKQtyqBZPHtST8ny5GNHMZyDfWVSg3wePPqIbkuAohdaTQ8I6jO/s1600/azure-web-app-linux-node.js+-+28+-+creating+the+Web+App+code+with+Node+Express+Generator+2.png.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3nsURurQJ5JXO-QgtL0tzO0bQ3KJmiA-dcfiJuPyi4VrA0uswsRJ64otAbZAoyPZ1uA9z5R95BlNZVUW2-QfF6lRhkyKQtyqBZPHtST8ny5GNHMZyDfWVSg3wePPqIbkuAohdaTQ8I6jO/s1000/azure-web-app-linux-node.js+-+28+-+creating+the+Web+App+code+with+Node+Express+Generator+2.png.png" /></a>
<br />
<br />
As adviced by the creation program, change directory to go to the Node.js Express application code directory, install the dependencies:
<br />
<pre class="code-standard" style="padding-left: 15px;">cd WebApp-Linux-Node
npm install
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdRTvCDyCUEbtwtHskR5ZfrMHE6P_w7IOnwKnq9HSIh9utNfqpgnE2TqqVGajFnuj2rd3VWZj4TYltu2pUjiegnOjaB8TiIZ9IiobT1a11vtMlsrtFkscMB9vWrM6m8BnpAnXQU59zSVXE/s1600/azure-web-app-linux-node.js+-+29+-+creating+the+Web+App+code+with+Node+Express+Generator+-+changing+directory+and+installing+dependencies.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdRTvCDyCUEbtwtHskR5ZfrMHE6P_w7IOnwKnq9HSIh9utNfqpgnE2TqqVGajFnuj2rd3VWZj4TYltu2pUjiegnOjaB8TiIZ9IiobT1a11vtMlsrtFkscMB9vWrM6m8BnpAnXQU59zSVXE/s1000/azure-web-app-linux-node.js+-+29+-+creating+the+Web+App+code+with+Node+Express+Generator+-+changing+directory+and+installing+dependencies.png" /></a>
<br />
<br />
Then, start the Node.js Express application locally by typing:
<br />
<pre class="code-standard" style="padding-left: 15px;">npm start
</pre>
and opening this url in a browser:
<br />
<pre class="code-standard" style="padding-left: 15px;">http://localhost:3000
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDnjgGbgkI_RuuzZS_cvFGHzfjmBnCRzJbnKVwy89Uzq3nxJSOWiPrE9P05zu7Mp1J297pEsrI9xrixp9ug7tv2GZ1N3FRPnz9pusm2oILlzrxDjLZ9Oe0IPoZfkj9yPhq0MmMGgOJs1du/s1600/azure-web-app-linux-node.js+-+30+-+creating+the+Web+App+code+with+Node+Express+Generator+-+testing+the+web+app+code+locally.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDnjgGbgkI_RuuzZS_cvFGHzfjmBnCRzJbnKVwy89Uzq3nxJSOWiPrE9P05zu7Mp1J297pEsrI9xrixp9ug7tv2GZ1N3FRPnz9pusm2oILlzrxDjLZ9Oe0IPoZfkj9yPhq0MmMGgOJs1du/s1000/azure-web-app-linux-node.js+-+30+-+creating+the+Web+App+code+with+Node+Express+Generator+-+testing+the+web+app+code+locally.png" /></a>
<br />
<br />
<h2>
Deploying the Node.js Express application to an Azure Linux Web App</h2>
<h3>
Setting the deployment mode</h3>
Locate the deployment center menu item of your Azure Linux Web App in the Azure Portal and oepn it.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoXa-gtPgIEU7zzYw5UxGBAGo0ZzGW0fgyfENgQiPBYzOa7ufqkgZRx9PuZ-VehUHbYpMf49YgGRdwO9V8w_kmAp5vZH2olDiK5FAtM6IQULwEEIzgU97ih0LH7OMu31lvM79wM3hq6fIA/s1600/azure-web-app-linux-node.js+-+30+-+deployment+center+-+local+git.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoXa-gtPgIEU7zzYw5UxGBAGo0ZzGW0fgyfENgQiPBYzOa7ufqkgZRx9PuZ-VehUHbYpMf49YgGRdwO9V8w_kmAp5vZH2olDiK5FAtM6IQULwEEIzgU97ih0LH7OMu31lvM79wM3hq6fIA/s1000/azure-web-app-linux-node.js+-+30+-+deployment+center+-+local+git.png" /></a>
<br />
<br />
Select "Local Git" then click on "Continue" button.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWGcG_584-3HFeoOL8GF7kcdALAzATJrMVRWmLSWnG4E4wseO4kBI_sS0hA1QhxBRujWg-UjKYUrB2ie7HzejeeGOjiIxJ2asCH8NyjqWqg7PVwWahnXUEVWtNubgPP7oNdZodAEC7jAfe/s1600/azure-web-app-linux-node.js+-+31+-+deployment+center+-+local+git+selected+-+continue.png" imageanchor="1"><img border="0" class="screenshot-standard" data-original-width="1000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWGcG_584-3HFeoOL8GF7kcdALAzATJrMVRWmLSWnG4E4wseO4kBI_sS0hA1QhxBRujWg-UjKYUrB2ie7HzejeeGOjiIxJ2asCH8NyjqWqg7PVwWahnXUEVWtNubgPP7oNdZodAEC7jAfe/s1600/azure-web-app-linux-node.js+-+31+-+deployment+center+-+local+git+selected+-+continue.png" /></a>
<br />
<br />
Select then, App Service build engine (Kudu) and click "Continue" button.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8eqZwvu2BX6jG-GOpuWLT0ex3Ad-iHZkoDZScN47TIQFAnhncRuySqzw-sAVI6-STe3udPnqzyG4M2IoAmNWxw0G3_qW3JvyyaoeEnUSttaYEIZsRzmTx6KflgJQMZ-eD7b9tQMC82XXp/s1600/azure-web-app-linux-node.js+-+34+-+App+Service+build+engine.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8eqZwvu2BX6jG-GOpuWLT0ex3Ad-iHZkoDZScN47TIQFAnhncRuySqzw-sAVI6-STe3udPnqzyG4M2IoAmNWxw0G3_qW3JvyyaoeEnUSttaYEIZsRzmTx6KflgJQMZ-eD7b9tQMC82XXp/s1000/azure-web-app-linux-node.js+-+34+-+App+Service+build+engine.png" /></a>
<br />
<br />
The App Service build engine of the Azure Kudu provides you with a git Url. You can:
<br />
<ul>
<li> clone it to add file locally to the repo and push them to your Azure Web App </li>
<li>or use it to add a remote to your existing git repo (it is that we are going to do)</li>
</ul>
Kudu behaves as a real git repo integrated to the Azure Web App. You will see more later after deployment.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLlMc_LKSwV_n9MrY1hl3ynPwNAK0wiZ_W_AutGLqc99NJQV-MsfHB2NwkjyYJSmG9gHVk90QoafNOsjXlua5hu2sUJMyGarwJ2sTNb7eB1mZGMv0wkjUY9-t2G3yGsAEzfZFoH1LMv5Ov/s1600/azure-web-app-linux-node.js+-+35+-+Azure+Web+App+Kudu+Git+repo.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLlMc_LKSwV_n9MrY1hl3ynPwNAK0wiZ_W_AutGLqc99NJQV-MsfHB2NwkjyYJSmG9gHVk90QoafNOsjXlua5hu2sUJMyGarwJ2sTNb7eB1mZGMv0wkjUY9-t2G3yGsAEzfZFoH1LMv5Ov/s1000/azure-web-app-linux-node.js+-+35+-+Azure+Web+App+Kudu+Git+repo.png" /></a>
<br />
<br />
click then on the "FTP Credentials" horizontal menu item to copy your credentials
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIOj00WQX_5ZUs6rm0Ji3u0CTxAbOQF6EvIPFEhAXUF3BAnFqbsOWE9EY7naQee7TiT_PylbZ1jJNp4jy-5BVuV3Jfr8grcB4paUZT2GQD08jh2d1Q4zrlRketngCPqnl8WyGiM8WU10_d/s1600/azure-web-app-linux-node.js+-+36+-+Copying+Azure+Web+App+FTP+Credentials.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIOj00WQX_5ZUs6rm0Ji3u0CTxAbOQF6EvIPFEhAXUF3BAnFqbsOWE9EY7naQee7TiT_PylbZ1jJNp4jy-5BVuV3Jfr8grcB4paUZT2GQD08jh2d1Q4zrlRketngCPqnl8WyGiM8WU10_d/s1000/azure-web-app-linux-node.js+-+36+-+Copying+Azure+Web+App+FTP+Credentials.png" /></a>
<br />
<br />
Paste them to a txt file for later.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgujuvyfaMBn1qKXxCHq8bKLZG1tyAHJXnFLfFM_Z0J0ycGgK2rR6kVexFBiHG3EPzdi9_OHwwfwkGQ4A0wvlIjm7OLCH5oPWORrgsnIFLFo6xnLd-jGrn_cltZDJikYixgeFgg6O64Wi47/s1600/azure-web-app-linux-node.js+-+38.png" imageanchor="1"><img border="0" class="screenshot-standard" data-original-width="1350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgujuvyfaMBn1qKXxCHq8bKLZG1tyAHJXnFLfFM_Z0J0ycGgK2rR6kVexFBiHG3EPzdi9_OHwwfwkGQ4A0wvlIjm7OLCH5oPWORrgsnIFLFo6xnLd-jGrn_cltZDJikYixgeFgg6O64Wi47/s1000/azure-web-app-linux-node.js+-+38.png" /></a>
<br />
<br />
<h3>
Deploying the Node.js application to the Azure Linux Web App</h3>
Go back to your command prompt and add a git file to your repo by typing:
<br />
<pre class="code-standard" style="padding-left: 15px;">git init .
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9P2yT_orKqfSFlhhuODyVkUNpDuVqZPHoqHROVHPjgn9n6cqGDYXkFimSksNDsMFXkwvpb-sLE8gMNUBZv4eGjjthonYnxXboU6REL890gkG3fOvPDDVaGoaFo9iUaVcCRP6PwDqFb_lH/s1600/azure-web-app-linux-node.js+-+38+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+init.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9P2yT_orKqfSFlhhuODyVkUNpDuVqZPHoqHROVHPjgn9n6cqGDYXkFimSksNDsMFXkwvpb-sLE8gMNUBZv4eGjjthonYnxXboU6REL890gkG3fOvPDDVaGoaFo9iUaVcCRP6PwDqFb_lH/s1000/azure-web-app-linux-node.js+-+38+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+init.png" /></a>
<br />
<br />
then, add your files to the deployment scope:
<br />
<pre class="code-standard" style="padding-left: 15px;">git add .
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBQCpJrIF4PjjjnNvPvz0eV-Qkn5kg3H3DolttmfnBM0qkIGkCAV6y3d4sEy0Os5Q5CLIWHfQbdZ_Uj1y7SxWsswyw5q_cCDTunE3se27ReXkNVMvUhJPb78iXywMKSArcQiZU6NaTQO7C/s1600/azure-web-app-linux-node.js+-+39+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+status.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBQCpJrIF4PjjjnNvPvz0eV-Qkn5kg3H3DolttmfnBM0qkIGkCAV6y3d4sEy0Os5Q5CLIWHfQbdZ_Uj1y7SxWsswyw5q_cCDTunE3se27ReXkNVMvUhJPb78iXywMKSArcQiZU6NaTQO7C/s1000/azure-web-app-linux-node.js+-+39+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+status.png" /></a>
<br />
<br />
commit this adding:
<br />
<pre class="code-standard" style="padding-left: 15px;">git commit -m "initial commit"
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjRHK4oxX72kOGk_b5w9nBhEySH_WiNjkEPDvmmLDWsBVaEXAXN4X2U2vF4m7cFflMb6Fj0mKVfZhxk1lI-fR0wOosczeN8TSb587KEyWHL4kcCGN4Sqf7JtkOaC4OpOXHfsHDxzMaAhPG/s1600/azure-web-app-linux-node.js+-+40+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+status+after+git+add.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjRHK4oxX72kOGk_b5w9nBhEySH_WiNjkEPDvmmLDWsBVaEXAXN4X2U2vF4m7cFflMb6Fj0mKVfZhxk1lI-fR0wOosczeN8TSb587KEyWHL4kcCGN4Sqf7JtkOaC4OpOXHfsHDxzMaAhPG/s1000/azure-web-app-linux-node.js+-+40+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+status+after+git+add.png" /></a>
<br />
<br />
add the Azure Web App git url as a remote destination to your Git configuration:
<br />
<pre class="code-standard" style="padding-left: 15px;">git add remote add AzureWebApp <git url in the deployment center overview>
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZLTksv9pQQsVLNdOzxyplnlvHaYdrX4ZyrKYBG3R2IhEgLiaX7D6o0g_7cQzAOqagkxp3p9ks-2nnFdVHOfmvOIQY40JxpDFe-H-UXZ0M1I9jqYheTeqO5YUZ6GWyJEkR2zRBz3GiOauv/s1600/azure-web-app-linux-node.js+-+41+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+remote+add+.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZLTksv9pQQsVLNdOzxyplnlvHaYdrX4ZyrKYBG3R2IhEgLiaX7D6o0g_7cQzAOqagkxp3p9ks-2nnFdVHOfmvOIQY40JxpDFe-H-UXZ0M1I9jqYheTeqO5YUZ6GWyJEkR2zRBz3GiOauv/s1000/azure-web-app-linux-node.js+-+41+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+remote+add+.png" /></a>
<br />
<br />
finally push your files to the Linux Azure Web App
<br />
<pre class="code-standard" style="padding-left: 15px;">git push --set-upstream AzureWebApp master
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT9lxZTg42CN-c-DrPGtUb_YYdd_9HqL_XN4BQyAEPcJppR8c88IT0sIdDPMKvpZ21udjfs086cQd2uK_72b7-Bvw8bZ__9vFyH9n-KSR26LgOGMzCd6CTp4lmkFw35QpMepOXo65Crna-/s1600/azure-web-app-linux-node.js+-+42+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+push.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT9lxZTg42CN-c-DrPGtUb_YYdd_9HqL_XN4BQyAEPcJppR8c88IT0sIdDPMKvpZ21udjfs086cQd2uK_72b7-Bvw8bZ__9vFyH9n-KSR26LgOGMzCd6CTp4lmkFw35QpMepOXo65Crna-/s1000/azure-web-app-linux-node.js+-+42+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+-+git+push.png" /></a>
<br />
<br />
You are prompted for your crendentials. Use the ones pasted previously.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgirs8rhXzGueiLNOKWTvGaD5LbzqL4a3gjAohK7pSf_FKIZSAC44rU-jqNLl3mOwS5T_KNyz5kADNn673rLnMR8MWEc_9KUe_kt5IfC2adzdu_8h4yOPlpqTEFPUrWi89UBT3LFhrGpTLG/s1600/azure-web-app-linux-node.js+-+43+-+entering+credentials+after+git+push.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgirs8rhXzGueiLNOKWTvGaD5LbzqL4a3gjAohK7pSf_FKIZSAC44rU-jqNLl3mOwS5T_KNyz5kADNn673rLnMR8MWEc_9KUe_kt5IfC2adzdu_8h4yOPlpqTEFPUrWi89UBT3LFhrGpTLG/s1000/azure-web-app-linux-node.js+-+43+-+entering+credentials+after+git+push.png" /></a>
<br />
<br />
This is the deployment screen shot. You can notice that Kudu builds the code, executes commands like npm install...
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDaDKJBrF_EJocd4ugPBjR9SaZRe9pwHUP1tV5vgubj2XcPifQUE4FehVWzyD0X0OLhSPK9B0m-c_0KM9rqPkulTuHIqUh4eeBBBMe128_OxsZIx8rr3HLiUy8qU0zrQ9eM8HDT5HqmcR9/s1600/azure-web-app-linux-node.js+-+44+-+node.js+application+deployment+to+linuw+azure+wab+app+using+git+push.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDaDKJBrF_EJocd4ugPBjR9SaZRe9pwHUP1tV5vgubj2XcPifQUE4FehVWzyD0X0OLhSPK9B0m-c_0KM9rqPkulTuHIqUh4eeBBBMe128_OxsZIx8rr3HLiUy8qU0zrQ9eM8HDT5HqmcR9/s1000/azure-web-app-linux-node.js+-+44+-+node.js+application+deployment+to+linuw+azure+wab+app+using+git+push.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvhKGLZXOwV8qYHOxMhLK3oCG1mq5LJME3eAKqQumApUy26DwCp-6l3-TXQnkPNeqf7_M9FPNu7hI9AeHEuY36imZOOo7xEfYNIy-5oE6nHskrzMmof6dQvgpydhXDSOLC-h9T2kD9wyQZ/s1600/azure-web-app-linux-node.js+-+45+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+2.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvhKGLZXOwV8qYHOxMhLK3oCG1mq5LJME3eAKqQumApUy26DwCp-6l3-TXQnkPNeqf7_M9FPNu7hI9AeHEuY36imZOOo7xEfYNIy-5oE6nHskrzMmof6dQvgpydhXDSOLC-h9T2kD9wyQZ/s1000/azure-web-app-linux-node.js+-+45+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+2.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcwGl_qYwSzvd1r-Ny79jsOburUhlalTPtbfbXcg1c_l8CwBQkyNrkYpr9BQl4oNR2XOjsG9G3Vtklfw5dA2IJWMFCl1mTIciHeAXsgcqEm6_oD7PwZu8wdS9Mvp0rPcbN9EFoS2rgAxVw/s1600/azure-web-app-linux-node.js+-+46+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+3.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcwGl_qYwSzvd1r-Ny79jsOburUhlalTPtbfbXcg1c_l8CwBQkyNrkYpr9BQl4oNR2XOjsG9G3Vtklfw5dA2IJWMFCl1mTIciHeAXsgcqEm6_oD7PwZu8wdS9Mvp0rPcbN9EFoS2rgAxVw/s1000/azure-web-app-linux-node.js+-+46+-+node.js+application+deployment+to+linux+azure+web+app+using+git+push+3.png" /></a>
<br />
<br />
Finally, if you go back to the Deployment Center of your Linux Azure Web App, you see the trace of the deployment just as if the Deployment Center was a git repo with the message of your last commit!
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbZVs4JK33_DUadMsK4A09v1b_gBz5KWHKJeTYYlx1eLoKstIC3N7ExOJafkia22YY44xCD4lj0I86yv-Vwbbk-wfBQjVg_Qwtwa-eFCzvvb57NPQxmMU20gVyaU_j77PhaD7bfoMpDjWH/s1600/azure-web-app-linux-node.js+-+47+-+node.js+application+deployed+to+linux+azure+web+app+using+git+push+3.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbZVs4JK33_DUadMsK4A09v1b_gBz5KWHKJeTYYlx1eLoKstIC3N7ExOJafkia22YY44xCD4lj0I86yv-Vwbbk-wfBQjVg_Qwtwa-eFCzvvb57NPQxmMU20gVyaU_j77PhaD7bfoMpDjWH/s1000/azure-web-app-linux-node.js+-+47+-+node.js+application+deployed+to+linux+azure+web+app+using+git+push+3.png" /></a>
<br />
<br />
You can go to the overview page of your Linux Azure Web App to click the Url of the Web App.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHRwqgB8AA4BcE4JemVu85DeHpf6l_GQMLlK3AhUT1pA4pNV9hn1_-fn0UfxJcFsYUmOAvuzoU9ZSU0djUfn9OI5x91jTW4DjnK-20B_XPLC4w8yts9vdRmZWUEOphBc2E5EWhbtT_nHbX/s1600/azure-web-app-linux-node.js+-+50+-+overview.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHRwqgB8AA4BcE4JemVu85DeHpf6l_GQMLlK3AhUT1pA4pNV9hn1_-fn0UfxJcFsYUmOAvuzoU9ZSU0djUfn9OI5x91jTW4DjnK-20B_XPLC4w8yts9vdRmZWUEOphBc2E5EWhbtT_nHbX/s1000/azure-web-app-linux-node.js+-+50+-+overview.png" /></a>
<br />
<br />
And check that the Linux Azure Web App is serving your Node.js application successfully!
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDeUWRvz_TZ8llLDIgeUiTl_L77cdtrOWxEDq_EenglEiz9rwK9c_BjMKJqeEW_6Aj8yzfpzHT1Ud8YxBFkUc7gfl0sJBiADybozVDKtlSUfQ4wHc2gi0Ia-TIXYpSdZz7V84lJzIWZ7m/s1600/azure-web-app-linux-node.js+-+52+-+node.js+application+succesfully+deployed+to+azure+linux+web+app+and+running.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDeUWRvz_TZ8llLDIgeUiTl_L77cdtrOWxEDq_EenglEiz9rwK9c_BjMKJqeEW_6Aj8yzfpzHT1Ud8YxBFkUc7gfl0sJBiADybozVDKtlSUfQ4wHc2gi0Ia-TIXYpSdZz7V84lJzIWZ7m/s1000/azure-web-app-linux-node.js+-+52+-+node.js+application+succesfully+deployed+to+azure+linux+web+app+and+running.png" /></a>
<br />
<br />
<h2>
Using the SSH tool to check the deployment</h2>
You can now navigate with the SSH tool to check your Web App folders and see the files:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOmb3UBVwt7xzdrNNKjT8P3hKTsVPPHOWecuyWeB2tGqItVJpykiZJpCwe7jtG80CQEDlExR0WOS3eBiNYqb7kxRTJITwAdyTO_16XCM6K_0hL1SU1zP1VJkvmPDsMMJneBuZb6zoBGNy2/s1600/azure-web-app-linux-node.js+-+53+-+node.js+application+deployed+to+linux+azure+web+app+-+navigating+with+ssh+tool.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOmb3UBVwt7xzdrNNKjT8P3hKTsVPPHOWecuyWeB2tGqItVJpykiZJpCwe7jtG80CQEDlExR0WOS3eBiNYqb7kxRTJITwAdyTO_16XCM6K_0hL1SU1zP1VJkvmPDsMMJneBuZb6zoBGNy2/s1000/azure-web-app-linux-node.js+-+53+-+node.js+application+deployed+to+linux+azure+web+app+-+navigating+with+ssh+tool.png" /></a>
<br />
<br />
for example the www file in the bin folder. Notice that the 3000 port has not been changed and that the application is running anyway, the Web App take set the port using the process.env.PORT.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKHEV0IdVN06cjr8F_5WjL58_9di8KgkWbQij_ra0ELRdvUkGoGvlMzcdX-SZhVU_W-51n24QUQd19lD4UimUZ-FNT2KObJQnzqVHhaC483NFhzGoCAruZlqehyphenhyphenS3SwHS374CVVu4w3zg5/s1600/azure-web-app-linux-node.js+-+54+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+www+file+%25282%2529.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKHEV0IdVN06cjr8F_5WjL58_9di8KgkWbQij_ra0ELRdvUkGoGvlMzcdX-SZhVU_W-51n24QUQd19lD4UimUZ-FNT2KObJQnzqVHhaC483NFhzGoCAruZlqehyphenhyphenS3SwHS374CVVu4w3zg5/s1000/azure-web-app-linux-node.js+-+54+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+www+file+%25282%2529.png" /></a>
<br />
<br />
We can also open the oryx manifest that has been created during the deployment
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBjBAHcjoswnM8wlBBa7Hijc9v_-r2IbiVxzK1Eg3b0QUvuqCe4Fq_EfSHIKAZ1J4SwruE09dpVYcyTXXwbt3iKC8oHJMoDai1DhC_aVoSzzfS5VHCX6i8JmXmV9qCLZdgbiSl-gz2Stgm/s1600/azure-web-app-linux-node.js+-+55+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+oryx+manifest.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBjBAHcjoswnM8wlBBa7Hijc9v_-r2IbiVxzK1Eg3b0QUvuqCe4Fq_EfSHIKAZ1J4SwruE09dpVYcyTXXwbt3iKC8oHJMoDai1DhC_aVoSzzfS5VHCX6i8JmXmV9qCLZdgbiSl-gz2Stgm/s1000/azure-web-app-linux-node.js+-+55+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+oryx+manifest.png" /></a>
<br />
<br />
and check the deployment logs:
<br />
home > logFiles > Kudu > deployment
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiog1R8rwepOyi-Gg58cY0Krjg-lU_HqBJSQK3Cua2I_T_5jS5gCIPaiAUUqGFbOLYMSOo2cvgrkLmoIZwbHUICwTyVPC-W32aS0I4B9pPUlEJYVXNigczKDCIfm5H1iSlR-TqXcUmcoYCd/s1600/azure-web-app-linux-node.js+-+56+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+deployment+logs.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiog1R8rwepOyi-Gg58cY0Krjg-lU_HqBJSQK3Cua2I_T_5jS5gCIPaiAUUqGFbOLYMSOo2cvgrkLmoIZwbHUICwTyVPC-W32aS0I4B9pPUlEJYVXNigczKDCIfm5H1iSlR-TqXcUmcoYCd/s1000/azure-web-app-linux-node.js+-+56+-+node.js+application+deployed+to+azure+linux+webapp+-+navigating+with+ssh+tool+-+displaying+deployment+logs.png" /></a>
<br />
<br />
<h2>
Performing development on the Express API</h2>
Assume we want now to display a contact list from our API. You can find the complete source code of this sample in my <a href="https://github.com/MarcCharmois/app-service-linux-api-node-sample">github repo: app-service-linux-api-node-sample</a>.
<br />
<br />
<h3>
1. Adding routes to app.js</h3>
Open app.js in a code editor and define a new route for your contactlist:
<br />
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 19px; padding-left: 5px; white-space: pre;"><span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">indexRouter</span> = <span style="color: #dcdcaa;">require</span>(<span style="color: #ce9178;">'./routes/index'</span>);
<span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">usersRouter</span> = <span style="color: #dcdcaa;">require</span>(<span style="color: #ce9178;">'./routes/users'</span>);
<span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">contactsRouter</span> = <span style="color: #dcdcaa;">require</span>(<span style="color: #ce9178;">'./routes/contacts'</span>);<span style="color: #6a9955;">//adding a router for contacts</span>
<span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">app</span> = <span style="color: #dcdcaa;">express</span>();
<span style="color: #6a9955;">// view engine setup</span>
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">set</span>(<span style="color: #ce9178;">'views'</span>, <span style="color: #9cdcfe;">path</span>.<span style="color: #dcdcaa;">join</span>(<span style="color: #9cdcfe;">__dirname</span>, <span style="color: #ce9178;">'views'</span>));
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">set</span>(<span style="color: #ce9178;">'view engine'</span>, <span style="color: #ce9178;">'pug'</span>);
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #dcdcaa;">logger</span>(<span style="color: #ce9178;">'dev'</span>));
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #9cdcfe;">express</span>.<span style="color: #dcdcaa;">json</span>());
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #9cdcfe;">express</span>.<span style="color: #dcdcaa;">urlencoded</span>({ <span style="color: #9cdcfe;">extended:</span> <span style="color: #569cd6;">false</span> }));
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #dcdcaa;">cookieParser</span>());
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #9cdcfe;">express</span>.<span style="color: #dcdcaa;">static</span>(<span style="color: #9cdcfe;">path</span>.<span style="color: #dcdcaa;">join</span>(<span style="color: #9cdcfe;">__dirname</span>, <span style="color: #ce9178;">'public'</span>)));
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #ce9178;">'/'</span>, <span style="color: #9cdcfe;">indexRouter</span>);
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #ce9178;">'/users'</span>, <span style="color: #9cdcfe;">usersRouter</span>);
<span style="color: #9cdcfe;">app</span>.<span style="color: #dcdcaa;">use</span>(<span style="color: #ce9178;">'/contacts'</span>, <span style="color: #9cdcfe;">contactsRouter</span>);<span style="color: #6a9955;">//adding a route for contacts</span>
</pre>
<br />
<h3>
2. Adding the data</h3>
Create a folder at the root of your API and name it data.
Create a json file named contacts.json in this folder.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAyGj44cGCQfPF-0_cc748DvteI9cvUsSz2onw0yLIurUQyvgWKeVBORFqZ1AhhzN0gIhBOWliIRB-glgmhpu9OvqQ-YrD3if45mM8c6wBLuJ7ZYNVWNxFC1xDTBhl8GAevuNEVysqW7tQ/s1600/azure-web-app-linux-node.js+-+57+-+node.js+application+deployed+to+azure+linux+webapp+-adding+datat+to+the+api.png" imageanchor="1"><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAyGj44cGCQfPF-0_cc748DvteI9cvUsSz2onw0yLIurUQyvgWKeVBORFqZ1AhhzN0gIhBOWliIRB-glgmhpu9OvqQ-YrD3if45mM8c6wBLuJ7ZYNVWNxFC1xDTBhl8GAevuNEVysqW7tQ/s1000/azure-web-app-linux-node.js+-+57+-+node.js+application+deployed+to+azure+linux+webapp+-adding+datat+to+the+api.png" /></a>
<br />
<br />
This is the json to paste in the file:
<br />
<br />
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 19px; padding-left: 5px; white-space: pre;">[
{
<span style="color: #9cdcfe;">"id"</span>:<span style="color: #b5cea8;">1</span>,
<span style="color: #9cdcfe;">"name"</span>:<span style="color: #ce9178;">"Barney Poland"</span>,
<span style="color: #9cdcfe;">"email"</span>:<span style="color: #ce9178;">"barney@contoso.com"</span>
},
{
<span style="color: #9cdcfe;">"id"</span>:<span style="color: #b5cea8;">2</span>,
<span style="color: #9cdcfe;">"name"</span>:<span style="color: #ce9178;">"Lacy Barrera"</span>,
<span style="color: #9cdcfe;">"email"</span>:<span style="color: #ce9178;">"lacy@contoso.com"</span>
},
{
<span style="color: #9cdcfe;">"id"</span>:<span style="color: #b5cea8;">3</span>,
<span style="color: #9cdcfe;">"name"</span>:<span style="color: #ce9178;">"Lora Riggs"</span>,
<span style="color: #9cdcfe;">"email"</span>:<span style="color: #ce9178;">"lora@contoso.com"</span>
}
]
</pre>
<h3>
3. Create the route</h3>
Create a contacts.js file in the "routes" folder:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhv5nzzfjpvQG5BdWnr7eU-RRVM00BF5EDmGwYzHtbK_4eApqf_tyYcxVxkXo9EReLK7l474EkNjtGOcgahyRQaOaPjWq9lo-rib0UqXYy2axRSW9PsKV06pHozypAH-SniqMBfAiqYn5qS/s1600/azure-web-app-linux-node.js+-+58+-+node.js+application+deployed+to+azure+linux+webapp+-adding+route+to+the+api.png" imageanchor="1"><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhv5nzzfjpvQG5BdWnr7eU-RRVM00BF5EDmGwYzHtbK_4eApqf_tyYcxVxkXo9EReLK7l474EkNjtGOcgahyRQaOaPjWq9lo-rib0UqXYy2axRSW9PsKV06pHozypAH-SniqMBfAiqYn5qS/s1000/azure-web-app-linux-node.js+-+58+-+node.js+application+deployed+to+azure+linux+webapp+-adding+route+to+the+api.png" /></a>
<br />
<br />
This is the js code to paste in:
<br />
<br />
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;padding-left:5px;">
<span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">express</span> = <span style="color: #dcdcaa;">require</span>(<span style="color: #ce9178;">'express'</span>);
<span style="color: #569cd6;">var</span> <span style="color: #9cdcfe;">router</span> = <span style="color: #9cdcfe;">express</span>.<span style="color: #dcdcaa;">Router</span>();
<span style="color: #9cdcfe;">router</span>.<span style="color: #dcdcaa;">get</span>(<span style="color: #ce9178;">'/'</span>, <span style="color: #569cd6;">function</span>(<span style="color: #9cdcfe;">req</span>, <span style="color: #9cdcfe;">res</span>, <span style="color: #9cdcfe;">next</span>) {
<span style="color: #9cdcfe;">res</span>.<span style="color: #dcdcaa;">sendFile</span>(<span style="color: #ce9178;">"/data/contacts.json"</span>,{ <span style="color: #9cdcfe;">root:</span> <span style="color: #ce9178;">"./"</span> });
})
<span style="color: #4ec9b0;">module</span>.<span style="color: #4ec9b0;">exports</span> = <span style="color: #9cdcfe;">router</span>;
</pre>
<h3>
4. Testing locally</h3>
you can then test your new code locally by executing a npm start:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUO0khRWCEPyZmaQejIupDL7i18NAapPkorEwbBMhb1Teonvn8hNQ0QEoh6WwDpQIWLMkft6u5-ynYG6wRxJASTWGGEd__UZpcwVatH2cPBoMt5kHfB3ARgcZ_tvXxhqp_yhuaFCicuKm0/s1600/azure-web-app-linux-node.js+-+59+-+node.js+application+deployed+to+azure+linux+webapp+-+testing+the+api+locally+-+npm+start.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUO0khRWCEPyZmaQejIupDL7i18NAapPkorEwbBMhb1Teonvn8hNQ0QEoh6WwDpQIWLMkft6u5-ynYG6wRxJASTWGGEd__UZpcwVatH2cPBoMt5kHfB3ARgcZ_tvXxhqp_yhuaFCicuKm0/s1000/azure-web-app-linux-node.js+-+59+-+node.js+application+deployed+to+azure+linux+webapp+-+testing+the+api+locally+-+npm+start.png" class="screenshot-standard" /></a>
<br>
<br>
and browsing to :
<br>
http://localhost:3000/contacts
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzP9hAnl5A9VgW-R7clPzPdn5GaDFbQ_BsGOhLMt2Oir976HOYhKX-nriUAsaE2Deijwp88mLZJ-Nq9FVC-ZfbmMEOwRfk0ExXR_MCca1GWRKFVeDwLLWCT7vTmdcwwxF16We1iDNBHmmM/s1600/azure-web-app-linux-node.js+-+59+-+node.js+application+deployed+to+azure+linux+webapp+-+testing+the+api+locally+-+browser.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzP9hAnl5A9VgW-R7clPzPdn5GaDFbQ_BsGOhLMt2Oir976HOYhKX-nriUAsaE2Deijwp88mLZJ-Nq9FVC-ZfbmMEOwRfk0ExXR_MCca1GWRKFVeDwLLWCT7vTmdcwwxF16We1iDNBHmmM/s1000/azure-web-app-linux-node.js+-+59+-+node.js+application+deployed+to+azure+linux+webapp+-+testing+the+api+locally+-+browser.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>
4. Deployment to the Azure Linux Web App</h3>
You can then push your code to the Azure Linux Web App
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivxkCWxzRhjI1sPN0CNPqilYnNP8lAOwq_TDraQWs6G78d1UOcjxpnOq5raDG6A_HGmSI9taGW-W8BcCxprIPqOweqrPjsbfcxqtBD22j8_Ejb2uaJF5IZJ3MbefBpMHqsSJYpsQppPctY/s1600/azure-web-app-linux-node.js+-+60+-+node.js+application+deployed+to+azure+linux+webapp+-+deploying+node.js+api+to+azure+linux+web+app.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivxkCWxzRhjI1sPN0CNPqilYnNP8lAOwq_TDraQWs6G78d1UOcjxpnOq5raDG6A_HGmSI9taGW-W8BcCxprIPqOweqrPjsbfcxqtBD22j8_Ejb2uaJF5IZJ3MbefBpMHqsSJYpsQppPctY/s1000/azure-web-app-linux-node.js+-+60+-+node.js+application+deployed+to+azure+linux+webapp+-+deploying+node.js+api+to+azure+linux+web+app.png" class="screenshot-standard" /></a>
<br>
<br>
I had to restart the Web App after deployment to see the new feature of the Linux Web App Node.js API working:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg0c5zVCWpFUjz4gqB42q2uoyxq67onDvHyS6_OK12lkekKo1iCN2UXNVKrgGFdR1HDHsejAWH-bBealC9i3oBRs_d8FkWeADO3JF3rjAGbFiKCY50gTKyrE40RWasGclrG9MiUIm1Gf2l/s1600/azure-web-app-linux-node.js+-+61+-+node.js+application+deployed+to+azure+linux+webapp+-+restarting+the+azure+linux+web+app.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg0c5zVCWpFUjz4gqB42q2uoyxq67onDvHyS6_OK12lkekKo1iCN2UXNVKrgGFdR1HDHsejAWH-bBealC9i3oBRs_d8FkWeADO3JF3rjAGbFiKCY50gTKyrE40RWasGclrG9MiUIm1Gf2l/s1000/azure-web-app-linux-node.js+-+61+-+node.js+application+deployed+to+azure+linux+webapp+-+restarting+the+azure+linux+web+app.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigNYLHczWnAfHCGgL_QWhuQgmXDRll3y2iicXPadiSnSxx8rwm64KemvqzwQb6ItYhwnfk3qUdc1Fw8OhPywDvV9oudogNkEPoDPGptVafx_aIhdzBfk21t1XvWtKwi-6N6Co5WpDODFMO/s1600/azure-web-app-linux-node.js+-+62+-+node.js+application+deployed+to+azure+linux+webapp+-+new+feature+of+the+Node.js+api+on+the+azure+linux+web+app+working.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigNYLHczWnAfHCGgL_QWhuQgmXDRll3y2iicXPadiSnSxx8rwm64KemvqzwQb6ItYhwnfk3qUdc1Fw8OhPywDvV9oudogNkEPoDPGptVafx_aIhdzBfk21t1XvWtKwi-6N6Co5WpDODFMO/s1600/azure-web-app-linux-node.js+-+62+-+node.js+application+deployed+to+azure+linux+webapp+-+new+feature+of+the+Node.js+api+on+the+azure+linux+web+app+working.png" style="border: solid 1px silver;" class="screenshot-standard" /></a>
<br>
<br>
You can see the trace of your new deployment in the deployment center of your Azure Web App
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2qAP4EVOadZVbb-XHziCealKb7g-apZBhimySG-1NbBMitx9XaknD9ILamRisf32F6PomL7SkgDPp_mvOAVUGHofaLr5VI0ANBIbi6_0IkZ65XEdNziidJT6Y8HpFDbfaGyDtdT8EzKTT/s1600/azure-web-app-linux-node.js+-+63+-+node.js+application+deployed+to+azure+linux+webapp+-+new+feature+of+the+Node.js+api+on+the+azure+linux+web+app+working+-+trace+in+the+deployment.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2qAP4EVOadZVbb-XHziCealKb7g-apZBhimySG-1NbBMitx9XaknD9ILamRisf32F6PomL7SkgDPp_mvOAVUGHofaLr5VI0ANBIbi6_0IkZ65XEdNziidJT6Y8HpFDbfaGyDtdT8EzKTT/s1000/azure-web-app-linux-node.js+-+63+-+node.js+application+deployed+to+azure+linux+webapp+-+new+feature+of+the+Node.js+api+on+the+azure+linux+web+app+working+-+trace+in+the+deployment.png" class="screenshot-standard" /></a>
<br>
<br>
<h2> keep developping with Azure App Service Extension for Visual Studio Code</h2>
Regarding Windows Azure Web App we have good online tools to develop online. Regarding Linux, don't hesitate to use this super cool feature of VS code to connect to your tenant and keep developping from your desktop:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWH5ATWjeqDHXHC1tDP3yJFdWDzlENJQSi2IsXQNCkcbMajrEIc-l-bsmcNJh992WRNPZRKr1f0LLq7J7WilbpRSkj10yJCGG_B9upvm1zTMJ7FStkFYgr-mqSUPdf6ZAY4jD0lKMDyBtT/s1600/azure-web-app-linux-node.js+-+64+-+node.js+application+deployed+to+azure+linux+webapp+-+Work+on+your+file+from+VS+code+through+Azure+App+Service+Extension.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWH5ATWjeqDHXHC1tDP3yJFdWDzlENJQSi2IsXQNCkcbMajrEIc-l-bsmcNJh992WRNPZRKr1f0LLq7J7WilbpRSkj10yJCGG_B9upvm1zTMJ7FStkFYgr-mqSUPdf6ZAY4jD0lKMDyBtT/s1000/azure-web-app-linux-node.js+-+64+-+node.js+application+deployed+to+azure+linux+webapp+-+Work+on+your+file+from+VS+code+through+Azure+App+Service+Extension.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>
references</h2>
This post is based on this <a href="https://docs.microsoft.com/en-us/azure/app-service/containers/quickstart-nodejs">Microsoft documentation</a>.
<br>
<br>
Source code available in my <a href="https://github.com/MarcCharmois/app-service-linux-api-node-sample">github repo: app-service-linux-api-node-sample</a>.
<br />
<br /></div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-36935797686416418222019-08-30T01:14:00.005+02:002019-09-05T09:44:41.483+02:00Store Azure AD Audit Logs in an Azure Storage Table using an Azure Runbook<style>
.code-standard{
word-wrap:normal;
}
.code div{
padding:0;
margin:0;
border: solid 0px red;
}
h4{
padding-left:5px;
margin-left:10px;
font-size:14px;
font-weight:normal;
}
</style>
<h2>
Introduction</h2>
<div class="h2-paragraph">
In previous posts, I showed how to:
<br />
<ul>
<li>
<a href="https://mosshowto.blogspot.com/2019/08/azure-powershell-az-module-installation.html">Have a local PowerShell environment using the new Az module that works fine.
</a><br />
We will use Az module for the scripts of this tutorial.
</li>
<li>
<a href="https://mosshowto.blogspot.com/2019/08/azure-ad-logs-powershell-graph.html">Request Graph with PowerShell to get Azure AD Audit logs, using a Service Principal credentials and permissions.</a>
<br />In this post, we have understood the need to store the Azure AD audit logs for years for security concerns because they are flushed, at best every 30 days. This has been done using a storage solution. Microsoft offers several manual solutions but only the blob solution can store the logs for years and as the blobs are nested in different folders hourly, it is not the best solution to parse the logs later if needed. An Azure Storage Account table will be more useful to display the Azure AD Activity archived logs if needed for security concerns.
</li>
<li>
<a href="https://mosshowto.blogspot.com/2019/08/azure-ad-logs-powershell-azureadpreview.html">Use the AzureADPreview PowerShell module locally to get Azure AD Audit logs.</a> I showed how easy it is to use the preview module to quicly get the Azure AD activity logs (Audit and Sign-ins).
</li>
</ul>
We are now going to go further and store the Azure AD Audit logs into an Azure Storage Account table. We are going to do all this using PowerShell only and we will open the Azure Portal only to check the results of our scripts.
</div>
<h2>
Design</h2>
<div class="h2-paragraph">
The PowerShell script will:
<br />
<ul>
<li>
create resources:
<ul>
<li>a Storage Account, </li>
<li>a Storage Table in the Storage Account,</li>
<li>an Automation Account,</li>
<li>a PowerShell RunBook in the Automation Account.</li>
</ul>
</li>
<li>add credentials and variables to the Automation Account.</li>
<li>import the code of the runbook from a gist.</li>
<li>execute the runbook to import the Azure AD Audit logs from Azure Active Directory and store them into the Azure Storage Table.
</li>
<li>display the result of the runbook job.</li>
</ul>
</div>
<h2>
Prerequisites</h2>
<div class="h2-paragraph">
To do this tutorial you must:
<br />
<ul>
<li>Have access to an Azure tenant and to an Azure subscription of that tenant.</li>
<li>Have a Global Administrator account for that tenant.</li>
<li>Have the Azure AD Audit logs non empty (you can manually create user in Azure AD if needed or <a href="https://mosshowto.blogspot.com/2019/08/create-user-azure-ad-powershell.html">use this post to it using PowerShell</a>).</li>
<li>Have a local PowerShell environement with new Az module installed and working properly.</li>
</ul>
</div>
<h2>
Warning:</h2>
<div class="h2-paragraph">
This is a tutorial. <b>Do not never, ever do what we are going to do in a real IT department</b>:
<br />
<ul>
<li>
We are going to use the AzureADPreview module the use of which is not allowed for production matters.
</li>
<li>
We are going to use the Global Administrator credentials in our runbook that is strictly a bad idea, because, in a real company, if a malicious people can have access to the runbook and change the code (that is quite easy) , this people could perform catastrophies regarding Azure environements in this company.
</li>
</ul>
I will post an article later showing how the same use case is processed in a real company.
<br />
Now you are aware of that, let's start the tutorial.
</div>
<h2>
Tutorial</h2>
<div class="h2-paragraph">
<h3>
1. Connecting to Azure, setting the Subscription, AzContext, ResourceGroup</h3>
We need first to connect to Azure. Then we need to define the containers for our resources (Automation Account, runbook, Storage Account, Storage Table).
<br />
<ul>
<li>
<b>The Azure Subscription</b> is THE container in Azure. It that gathers all the costs of the resources at a first level, allows users to find the resources and administrators to easily define permissions. It is the main container to store resources in Azure.
</li>
<li>
<b>The Azure Resource Group</b> is a sub container within the subscription. It allows users and administrators to gather resources linked by a same project, topic,etc. Most of all, if you remove a resource group you remove all the resources inside of it. Very useful to create a bunch of resources test them and delete them to perform another test without any risk to touch to another resources in the subscription.
</li>
<li>
<b>The Azure Context</b> is like an invisible link to a subscription in our PowerShell session. In certain PowerShell cmdlets, we will not be necessarely asked to re-precise the subscription to impact each time. The cmdlet will be sometimes smarter enough to guess the subscription to impact because it is linked to the context. That's why, the context is a very important thing to check or define if needed.
</li>
</ul>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">
# Will be prompted to sign in via browser</span>
<span style="color: #7096ff;">Connect-AzAccount</span>
<span style="color: #6a9955;"># check the subsctiption available and choose one to work with</span>
<span style="color: #7096ff;">Get-AzSubscription</span>
<span style="color: #6a9955;">#define the subscription you want to work with</span>
<span style="color: #9ad7fa;">$subscriptionId</span>=<span style="color: #ce9178;">"your subscription id"</span>
<span style="color: #6a9955;">#Check what iz your AzContext</span>
<span style="color: #7096ff;">Get-AzContext</span>
<span style="color: #6a9955;"># Use set context if you need to change subscriptions.</span>
<span style="color: #7096ff;">Set-AzContext</span> -Subscription <span style="color: #9ad7fa;">$subscriptionId</span>
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisYGtC8G0EnoWfbjbJFFHRQ3SfO46KulZv3yoOd6FOR-xiNK8FptjHFkPeANkxdKZzgoxZbKNq2Ztvoa4nrh97Vf0N0K9YD9mmWWPmJQkvcrX3PlIPpPN7ZkoaHMomeLhJVKbXtRVhReEh/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+01+-+Connect-AzAccount+-+Get-AzSubscription+Get-AzContext.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisYGtC8G0EnoWfbjbJFFHRQ3SfO46KulZv3yoOd6FOR-xiNK8FptjHFkPeANkxdKZzgoxZbKNq2Ztvoa4nrh97Vf0N0K9YD9mmWWPmJQkvcrX3PlIPpPN7ZkoaHMomeLhJVKbXtRVhReEh/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+01+-+Connect-AzAccount+-+Get-AzSubscription+Get-AzContext.png" /></a>
<br />
<br />
Notice than, after my connection, my Azure Context was set on my Paas subscription. As I want to perform this tutorial on the Iaas one, I have to change the Context to point on the Iaas subscription.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitYeaHTe9ZCzKJYBfMV-yzdYWOvXSY2RUZvDceBVzJye3vXkFD7YxyrGgGE76bDFkI5SuVTNaGN-OYlQ29msv1UP6QObK1plBDb88qAGWWZSULR5hy1yRGl47BKaBZeFge_0i3dww0dgEa/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+03+-+Set-AzContext+check+AzContext.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitYeaHTe9ZCzKJYBfMV-yzdYWOvXSY2RUZvDceBVzJye3vXkFD7YxyrGgGE76bDFkI5SuVTNaGN-OYlQ29msv1UP6QObK1plBDb88qAGWWZSULR5hy1yRGl47BKaBZeFge_0i3dww0dgEa/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+03+-+Set-AzContext+check+AzContext.png" /></a>
<br />
<br />
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#New Resource Group</span>
<span style="color: #9ad7fa;">$Location</span> = <span style="color: #ce9178;">"francecentral"</span>
<span style="color: #9ad7fa;">$resourceGroupName</span> = <span style="color: #ce9178;">"azureADAuditLogs"</span>
<span style="color: #7096ff;">New-AzResourceGroup</span> -Name <span style="color: #9ad7fa;">$resourceGroupName</span> -location <span style="color: #9ad7fa;">$Location</span>
</pre>
If I go to the Portal, the Resource Group exists, but for another subscription.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7p_8f2jQg22p6KM3x-E-vz1Wkn5Plhtk6ruOrpFbzq1z2i23ER141OS8gzMvLFmKP-e2x8yq3_9cXs2awaqMoQgaVC_8WQsBPKdRlEtJNVtTrFxH06nvHtBOPrYKKEOw_yeNYd3NNGuRT/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+06+-+Azure+Portal+before+resource+group+creation.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7p_8f2jQg22p6KM3x-E-vz1Wkn5Plhtk6ruOrpFbzq1z2i23ER141OS8gzMvLFmKP-e2x8yq3_9cXs2awaqMoQgaVC_8WQsBPKdRlEtJNVtTrFxH06nvHtBOPrYKKEOw_yeNYd3NNGuRT/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+06+-+Azure+Portal+before+resource+group+creation.png" /></a>
<br />
<br />
After the cmdlet success
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwLKSqulBS-9o8crc9xClOLCM9ZuCCDomg97-shCJ7kCJqIoLDAwoePSjaKWIq04t_7YYaSOWuW0nvuGIrcQUyiNPNx_q3xjmwE55a7yXfDsIfccRcmWwhp0FsDzKlnOUSPWFcv8F7iPyZ/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+07+-+resource+group+creation.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwLKSqulBS-9o8crc9xClOLCM9ZuCCDomg97-shCJ7kCJqIoLDAwoePSjaKWIq04t_7YYaSOWuW0nvuGIrcQUyiNPNx_q3xjmwE55a7yXfDsIfccRcmWwhp0FsDzKlnOUSPWFcv8F7iPyZ/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+07+-+resource+group+creation.png" /></a>
<br />
<br />
We can see the new Resource Group in the Azure Portal within the good subscription.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC1f027yHcozJYZ0ij5nKqXoV_U3yCCNIDvJtZJyE3auXghf_pXZ0C0HE5BdDHi_RW0zc2myIN-ZqypOBvK86g1JEixW7KLYj-y1DqvyI2OTnxcmloTDnaT2IS_gXkM6seX7SIFcFEkOgL/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+08+-+portal+after+resource+group+creation.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC1f027yHcozJYZ0ij5nKqXoV_U3yCCNIDvJtZJyE3auXghf_pXZ0C0HE5BdDHi_RW0zc2myIN-ZqypOBvK86g1JEixW7KLYj-y1DqvyI2OTnxcmloTDnaT2IS_gXkM6seX7SIFcFEkOgL/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+08+-+portal+after+resource+group+creation.png" /></a>
<br />
<br />
We have all our first level containers now, we can thus create the resources within them.
<br />
<h3>
2. Creating the Automation Account</h3>
<b>An Automation Account</b> is both a resource, but also a container for one or several runbooks that can execute code on demand or based on schedule. The Automation Account can provide the runbook(s) with several items:
<br />
<ul>
<li>Variables that the runbook(s) can call and use.</li>
<li>Credentials (encrypted of course) that the runbook(s) can call and use to authenticate to Azure, Azure AD, etc.</li>
<li>Code modules that the runbook(s) can import and use.
</li>
</ul>
Let's create the automation account.
<br />
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;">
<span style="color: #6a9955;">#New Automation Account</span>
<span style="color: #9ad7fa;">$automationAccountName</span> = <span style="color: #ce9178;">"adlogs-automationAccount"</span>
<span style="color: #7096ff;">New-AzAutomationAccount</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -Name <span style="color: #9ad7fa;">$automationAccountName</span> -Location <span style="color: #9ad7fa;">$Location</span> -Plan Free
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPiZNVYlFn0FFwpTQr1Dj2FU6qyt0bskPwNS5JSrdNzSHBREJymwW2l7__1WGhkTjwYs_0BVdoIBi9Zsrcv0ET76ebIRI0PhoMf4g1GWfFMLVFslwULTPFzDzVN3K3MPeFf73jMJRZAYjs/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+09+-+ADLogs-automationAccount+created+PowerShel+Windows.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPiZNVYlFn0FFwpTQr1Dj2FU6qyt0bskPwNS5JSrdNzSHBREJymwW2l7__1WGhkTjwYs_0BVdoIBi9Zsrcv0ET76ebIRI0PhoMf4g1GWfFMLVFslwULTPFzDzVN3K3MPeFf73jMJRZAYjs/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+09+-+ADLogs-automationAccount+created+PowerShel+Windows.png" /></a>
<br />
<br />
We had a successful confirmation in the Powershell window and we can check that the Automation Account has been created successfully in the portal:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt8aoFXG2lhzUXpSDMsT-K7Q7Ymihq4wNeffDs1d_lO4JiguT31RmXbWeQp-JFw87W9kILVEnMLeJz80MROBPEc3FdIvql-5y4GrMEVy67MNFJhlAI4if3TIviljqUXag-OUSFH_2x8xh8/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+14+-+ADLogs-automationAccount+created+portal.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt8aoFXG2lhzUXpSDMsT-K7Q7Ymihq4wNeffDs1d_lO4JiguT31RmXbWeQp-JFw87W9kILVEnMLeJz80MROBPEc3FdIvql-5y4GrMEVy67MNFJhlAI4if3TIviljqUXag-OUSFH_2x8xh8/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+14+-+ADLogs-automationAccount+created+portal.png" /></a>
<br />
<br />
<h3>
3. Adding modules to the Automation Account</h3>
The runbook that we will create later within the Automation Account will have 2 tasks to do:
<br />
<ul>
<li>
Connect to Azure Active Directory to import the Audit Logs. There is a PowerShell module AzureADPreview that helps to do this very quicly with a single line cmdlet! Unfortunately, a standard Automation Account doesn't come with this module loaded so we have to import it. This module is in preview so as written previously it is not recommended by Microsoft to use it at work yet.
</li>
<li>
Then, export all the logs line by line in an Azure Storage Table. Here again, creating lines in an Azure Storage Table requires a specific module: AzureRMStorageTable. We have to import this module also in our Automation Account.
</li>
</ul>
<h3>
3.1 Adding module ADPreview to the Automation Account</h3>
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;">
<span style="color: #6a9955;">#Importing AzureADPreview module into Automation Account</span>
<span style="color: #9ad7fa;">$ModuleADPreview</span> = <span style="color: #ce9178;">"AzureADPreview"</span>
<span style="color: #9ad7fa;">$uriModuleADPreview</span> = (<span style="color: #7096ff;">Find-Module</span> <span style="color: #9ad7fa;">$ModuleADPreview</span>).RepositorySourceLocation + <span style="color: #ce9178;">'package/'</span> + <span style="color: #9ad7fa;">$ModuleADPreview</span>
<span style="color: #9ad7fa;">$uriModuleADPreview</span>
<span style="color: #7096ff;">New-AzAutomationModule</span> -Name <span style="color: #9ad7fa;">$ModuleADPreview</span> -ContentLinkUri <span style="color: #9ad7fa;">$uriModuleADPreview</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span>
</pre>
<div class="h2-paragraph">
Above are the cmdlets to import the module AzureADPreview, and below, the result of them in the PowerShell window:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9D-dnknMtOqL3mVwXCaWfvUdJlBhZ0u0cd0VApAUzZE0JuohmE2txICKzBn96gIhNoLBHtn4tbTazW-xJObWhQe6DBRZKMJWWuZQxiFvKJwUWK-2Rbo5p6jT33_RCOa7CoO82FzgvyCzq/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+12+-+ADLogs-automationAccount+module+ADPrview+Importing+PowerShell+Windows.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9D-dnknMtOqL3mVwXCaWfvUdJlBhZ0u0cd0VApAUzZE0JuohmE2txICKzBn96gIhNoLBHtn4tbTazW-xJObWhQe6DBRZKMJWWuZQxiFvKJwUWK-2Rbo5p6jT33_RCOa7CoO82FzgvyCzq/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+12+-+ADLogs-automationAccount+module+ADPrview+Importing+PowerShell+Windows.png" /></a>
<br />
<br />
As soon as the cmdlet receives a response, we can see in the portal that the module is in a state "Importing":
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK-P7xuH8f52hY5DMyGDfwL1swF13A8YnK1G-zN9yqIIAfHOLSRwBxlhDgVQvot53j_yaOkfVGnrd43E97MGSpO2a52LgD2SvoMm-tDLUTx_3Ot3VCQOzJYfMaOCply4Z4ujqz_gws_fkg/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+13+-+ADLogs-automationAccount+module+ADPrview+Importing.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK-P7xuH8f52hY5DMyGDfwL1swF13A8YnK1G-zN9yqIIAfHOLSRwBxlhDgVQvot53j_yaOkfVGnrd43E97MGSpO2a52LgD2SvoMm-tDLUTx_3Ot3VCQOzJYfMaOCply4Z4ujqz_gws_fkg/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+13+-+ADLogs-automationAccount+module+ADPrview+Importing.png" /></a>
<br />
<br />
And soon imported and ready to use:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2SYwZpjuqxFlZ62PoGIFHYyebiHKw3QSI2enhtBo-Kk8Y-sphCncisOJlsy_9YJbjBQEF2_XZYcZwFYaDiWAxPcgdpUKuzbESLKmMd5SdYVUAUBQgtyiZpEXaZVU5NebjctqGBcFALAF9/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+14+-+ADLogs-automationAccount+module+ADPrview+Imported.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2SYwZpjuqxFlZ62PoGIFHYyebiHKw3QSI2enhtBo-Kk8Y-sphCncisOJlsy_9YJbjBQEF2_XZYcZwFYaDiWAxPcgdpUKuzbESLKmMd5SdYVUAUBQgtyiZpEXaZVU5NebjctqGBcFALAF9/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+14+-+ADLogs-automationAccount+module+ADPrview+Imported.png" /></a>
<br />
<br />
<h3>
3.2 Adding module AzureRMStorageTable to the Automation Account</h3>
Regarding this module, there is a somehow tricky explanation to do. This module is one of the most old modules of Azure since we had needed to store data in Storage Tables from the beginning of the portal. However, the version of Azure has increased and the name of the cmdlets also, we had AzureRM, and now Az, but regarding the storage the names stayed the sames. Furthermore, you notice that all our PowerShell cmdlets are based on new PowerShell Az module, but the current (2019-08-26) out-of-the-box Azure runbook created within an automation account is still using the AzureRM module!
<br />
So now we have 2 versions of the AzureRMStorageTable :
<br />
<ul>
<li>
The latest version (2.0) is compatible with the new module Az and is not compatible with the current (2019-08-26) out-of-the-box Azure runbook that is still using AzureRM . There is, by the way, no module named AzStorageTable.
</li>
<li>the 1.0.0.23 version is compatible with the module AzureRM, and as we are going to use the module AzureRMStorageTable within a runbook we have to import the 1.0.0.23 version of the AzureRMStorageTable because the out-of-the-box Azure runbook at date (2019-08-26) is still baseed on AzureRM.
</li>
</ul>
So here are the cmdlets to do it:
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#Importing AzureRmStorageTable module into Automation Account</span>
<span style="color: #9ad7fa;">$ModuleStorageTable</span> = <span style="color: #ce9178;">"AzureRmStorageTable"</span>
<span style="color: #9ad7fa;">$uriModuleStorageTable</span> = (<span style="color: #7096ff;">Find-Module</span> <span style="color: #9ad7fa;">$ModuleStorageTable</span>).RepositorySourceLocation + <span style="color: #ce9178;">'package/'</span> + <span style="color: #9ad7fa;">$ModuleStorageTable</span> + <span style="color: #ce9178;">'/1.0.0.23'</span>
<span style="color: #9ad7fa;">$uriModuleStorageTable</span>
<span style="color: #7096ff;">New-AzAutomationModule</span> -Name <span style="color: #9ad7fa;">$ModuleStorageTable</span> -ContentLinkUri <span style="color: #9ad7fa;">$uriModuleStorageTable</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span>
</pre>
<div class="h2-paragraph">
And the result at the execution:
<br />
In PowerShell
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXXyR6WBsthpFoJoDm0UttqvbMRIEp03-29fNkqQoublwiAh0brK5Js2H8mvx569bbp8ZExU2nyRMzSmqVbrCi0S0bVE8f0GjAdvwMfkP3vuKRUGIEW0JqKoUdUnRBXyY6vHroxuqvSWvA/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+15+-+ADLogs-automationAccount+module+AzureRMStorageTable+Importing+Powershell.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXXyR6WBsthpFoJoDm0UttqvbMRIEp03-29fNkqQoublwiAh0brK5Js2H8mvx569bbp8ZExU2nyRMzSmqVbrCi0S0bVE8f0GjAdvwMfkP3vuKRUGIEW0JqKoUdUnRBXyY6vHroxuqvSWvA/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+15+-+ADLogs-automationAccount+module+AzureRMStorageTable+Importing+Powershell.png" /></a>
<br />
<br />
and in the portal
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirZ5ZaVUfwYLjWeHbuVBLbismQ09yHLFmasm09O32disSepIVtJFB2-hQWRrCMgd58bTFyvLgJSEsuQH2BNzjKls006wxsp7njJ3_ENpTN80Y9AWwzSTpexRv6FYL-BZGKapfx5aIEBh_J/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+16+-+ADLogs-automationAccount+module+AzureRMStorageTable+Imported+portal.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirZ5ZaVUfwYLjWeHbuVBLbismQ09yHLFmasm09O32disSepIVtJFB2-hQWRrCMgd58bTFyvLgJSEsuQH2BNzjKls006wxsp7njJ3_ENpTN80Y9AWwzSTpexRv6FYL-BZGKapfx5aIEBh_J/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+16+-+ADLogs-automationAccount+module+AzureRMStorageTable+Imported+portal.png" /></a>
<br />
<br />
<h3>
4 Adding the credentials to the Automation Account</h3>
As written before we are going to add credentials to the Automation Account for them to be used by the runbook, and this will be the Azure Tenant Global Administrator credentials. As written before also, you cannot do this in a real company because is very unsafe, but this is only a tutorial in a demo tenant so for the quickness of the demo we are going to do this here.
<br />
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;">
<span style="color: #6a9955;">#New Credentials for the Automation Account</span>
<span style="color: #9ad7fa;">$automationCredentialsName</span> = <span style="color: #ce9178;">"azureADConnectAccount"</span>
<span style="color: #7096ff;">New-AzAutomationCredential</span> -Name <span style="color: #9ad7fa;">$automationCredentialsName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Value (<span style="color: #7096ff;">Get-Credential</span>)
</pre>
<div class="h2-paragraph">
<br />
When running the cmdlet, you are prompted for credentials. Enter the Global Administrator ones.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1USyqpc99mU1VsGGWA2dFiudEmnyG4eudjlV-4zA8KyQIF24srMZ3ibM7e3jI0VfxZfKH6IfMNRIOELT5x_hw9rmoANfFz1QXZHXvIvDJ1Do74fDoFk3_OYgAo3fxFnmlkuDNnyEzOq1c/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+17+-+ADLogs-automationAccount+credentials+prompted+PowerShell+window.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1USyqpc99mU1VsGGWA2dFiudEmnyG4eudjlV-4zA8KyQIF24srMZ3ibM7e3jI0VfxZfKH6IfMNRIOELT5x_hw9rmoANfFz1QXZHXvIvDJ1Do74fDoFk3_OYgAo3fxFnmlkuDNnyEzOq1c/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+17+-+ADLogs-automationAccount+credentials+prompted+PowerShell+window.png" /></a>
<br />
<br />
then you can check the creation in the PowerShell Window and in the Azure Portal:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1uMVfFKnPzCSp1_m_nSi1Nsbr0wLG2br0nzwQeBIJk0R2EvmS1haObSxKmxjcmFrY7l5WeqtQ34k_i6cWun2F1CPYYDnDyR0GLrsGcDxmwP-vSQ8UE_-UaP9S7sWS7prtBoEVlwkEz8-G/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+18+-+ADLogs-automationAccount+credentials+created+PowerShell+window.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1uMVfFKnPzCSp1_m_nSi1Nsbr0wLG2br0nzwQeBIJk0R2EvmS1haObSxKmxjcmFrY7l5WeqtQ34k_i6cWun2F1CPYYDnDyR0GLrsGcDxmwP-vSQ8UE_-UaP9S7sWS7prtBoEVlwkEz8-G/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+18+-+ADLogs-automationAccount+credentials+created+PowerShell+window.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaGArT5H5LXED3f7ezX-N_fbjPmlsXwk25d_1wowdyRnoarYaz2QrEgN6El6mEWL8CK1DjtOzhQLB28IoanR3KikUkkjX2WHlhI0rutq0KODdDMyR9zf9pm-ygXwZGJAuwB36629LCltr3/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+19+-+ADLogs-automationAccount+credentials+created+Azure+Portal.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaGArT5H5LXED3f7ezX-N_fbjPmlsXwk25d_1wowdyRnoarYaz2QrEgN6El6mEWL8CK1DjtOzhQLB28IoanR3KikUkkjX2WHlhI0rutq0KODdDMyR9zf9pm-ygXwZGJAuwB36629LCltr3/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+19+-+ADLogs-automationAccount+credentials+created+Azure+Portal.png" /></a>
<br />
<h3>
5. Adding variables to the automation account</h3>
the code executed by the runbook will be loaded later from a Gist. The runbook and its code, in order to perform their tasks successfully need information about :
<br />
<ul>
<li>
Credentials name
</li>
<li>
Subscription where the Storage Table is
</li>
<li>
Resource Group of this Subscription
</li>
<li>
Storage Account where the Storage Table is
</li>
<li>
Storage Table name
</li>
</ul>
Where are going to pass all these values to the runbook through variables within the Automation Account. We are creating first the variable the wich we know the value, we let the variable for the Storage Account and Table for later after having created the Storage Account and the Strorage Table.
<br />
Fill the <b>$subscriptionName value</b> with the name of the subscription you work with, the execute the code for the variables creation.
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#New variables for the Automation Account</span>
<span style="color: #9ad7fa;">$subscriptionName</span> = <span style="color: #ce9178;">""</span> <span style="color: #6a9955;">#the name of the subscription where you want to create automation account and storage account</span>
<span style="color: #7096ff;">New-AzAutomationVariable</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Name <span style="color: #ce9178;">"subscriptionName"</span> -Encrypted <span style="color: #569cd6;">$False</span> -Value <span style="color: #9ad7fa;">$subscriptionName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span>
<span style="color: #7096ff;">New-AzAutomationVariable</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Name <span style="color: #ce9178;">"resourceGroupName"</span> -Encrypted <span style="color: #569cd6;">$False</span> -Value <span style="color: #9ad7fa;">$resourceGroupName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span>
<span style="color: #7096ff;">New-AzAutomationVariable</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Name <span style="color: #ce9178;">"automationCredentialsName"</span> -Encrypted <span style="color: #569cd6;">$False</span> -Value <span style="color: #9ad7fa;">$automationCredentialsName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span>
</pre>
<div class="h2-paragraph">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvn23du0co2cz1lxIwPQWrYimB3R-eKDHNCZbxck-NbI2lQybw5hmsvl73KgsdAH3kzJk8iagN0u1_iiW3lbI89V76G7gUkcD5zp5uCIrvPM_t9cwvsMMAa8zS1SeLqzsA0KMF_RzuTfe/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+22+-+ADLogs-automationAccount+first+variables++created+PowerShell.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvn23du0co2cz1lxIwPQWrYimB3R-eKDHNCZbxck-NbI2lQybw5hmsvl73KgsdAH3kzJk8iagN0u1_iiW3lbI89V76G7gUkcD5zp5uCIrvPM_t9cwvsMMAa8zS1SeLqzsA0KMF_RzuTfe/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+22+-+ADLogs-automationAccount+first+variables++created+PowerShell.png" class="screenshot-standard" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtOMFj4sEabGyndNVW1AwKzyiE8tbAXmEl2uFv7GkBF7ewwSAN66-qUxkD3PSITYL9mGO0DJRs55O0uRWC-7rnaN7q2QWtj9GUAoWU14zaklfLl4BgFUm8cLkDisPThKc3PY7LY5bQ8D1/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+23+-+ADLogs-automationAccount+first+variables++created+Portal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtOMFj4sEabGyndNVW1AwKzyiE8tbAXmEl2uFv7GkBF7ewwSAN66-qUxkD3PSITYL9mGO0DJRs55O0uRWC-7rnaN7q2QWtj9GUAoWU14zaklfLl4BgFUm8cLkDisPThKc3PY7LY5bQ8D1/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+23+-+ADLogs-automationAccount+first+variables++created+Portal.png" class="screenshot-standard" /></a>
<br />
<h3>
5. Creating the Storage Account and the Storage Table</h3>
<h4>
5.2 Storage Account creation</h4>
A storage account name has to be unique worldwide, because its name define its Url. To be sure of the unicity of the name for anybody doing this tutorial, I use this trick :<br />
your tenant domain name (that is unique worldwide) + suffix + increment number. Everything has to be in lower case.
<br />
So <b>fill the value with your tenant domain for the $tenantDomain variable (lowercase)</b> and run the PowerShell cmdlets
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#New Storage Acount</span>
<span style="color: #9ad7fa;">$tenantDomain</span> = <span style="color: #ce9178;">""</span><span style="color: #6a9955;">#fill with your tenant domain</span>
<span style="color: #9ad7fa;">$storageAccountNameSuffix</span> = <span style="color: #ce9178;">"adlogs2"</span> <span style="color: #6a9955;">#increment the number each time you perform a new test (except if you delete the storage account after each test)</span>
<span style="color: #9ad7fa;">$storageaccountname</span> = <span style="color: #9ad7fa;">$tenantDomain</span> + <span style="color: #9ad7fa;">$storageAccountNameSuffix</span>
<span style="color: #9ad7fa;">$StorageAccount</span> = <span style="color: #7096ff;">New-AzStorageAccount</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -Name <span style="color: #9ad7fa;">$storageaccountname</span> -Location <span style="color: #9ad7fa;">$location</span> -SkuName Standard_RAGRS -Kind StorageV2
</pre>
<div class="h2-paragraph">
<br />
No response in PowerShell when created,...
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjNYnGviDVdCtuzBNNcbf8Bz-PnQRI2zqGY-a9jT7LvMc5pgCM5QE_GNOtI8x583SNNJCFbKX-gR1SROKp6wwlM3CSxh45lujuB7yrAlq0yVg0C8znk4xDSNqPjBIPgnbERsikfCj1kV8q/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+25-+Storage+Account+creation+PowerShell.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjNYnGviDVdCtuzBNNcbf8Bz-PnQRI2zqGY-a9jT7LvMc5pgCM5QE_GNOtI8x583SNNJCFbKX-gR1SROKp6wwlM3CSxh45lujuB7yrAlq0yVg0C8znk4xDSNqPjBIPgnbERsikfCj1kV8q/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+25-+Storage+Account+creation+PowerShell.png" /></a>
<br />
<br />
But it appears in the portal.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj1b8YzTEi2No3A2YTESmphhI519Bo5GHSL5C7lh2SbSRByw1o02aboFaCod_rHPhjS_AqhMLb_ErnmYCkKa1eKa8EAF87pVnWVkr8lKW-lprP-fk88B6yGm_RZThtkp9HbiJCydeIsAZx/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+26-+Storage+Account+creation+Portail.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj1b8YzTEi2No3A2YTESmphhI519Bo5GHSL5C7lh2SbSRByw1o02aboFaCod_rHPhjS_AqhMLb_ErnmYCkKa1eKa8EAF87pVnWVkr8lKW-lprP-fk88B6yGm_RZThtkp9HbiJCydeIsAZx/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+26-+Storage+Account+creation+Portail.png" /></a>
<br />
<br />
<h4>
5.3 Storage Table creation</h4>
For creating the table run the following cmdlets:
<br>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;">
<span style="color: #6a9955;">#New Storage Table</span>
<span style="color: #9ad7fa;">$tableName</span> = <span style="color: #ce9178;">"azureADAuditLogs"</span>
<span style="color: #9ad7fa;">$ctx</span> = <span style="color: #9ad7fa;">$storageAccount.Context</span>
<span style="color: #7096ff;">New-AzStorageTable</span> -Name <span style="color: #9ad7fa;">$tableName</span> -Context <span style="color: #9ad7fa;">$ctx</span>
</pre>
<br />
Table is created, the unique Url appears in PowerShell. That's why the storage account name has to be unique worldwide.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnDIEVE-p0MzoR7ETam2nSrYvizgUYD6f_OZ6-l7rg8duM-TeFLLnlVkN6dV_NC8vOVvTgrV0T2ALsyK8HqpJ-KkWD7VXBSDRfdSkMI_uj3kwXUulJquoUF2TVWFGrPNHn1hdtzCRvCnKb/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+28-+Table+Storage+creation+Powershell.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnDIEVE-p0MzoR7ETam2nSrYvizgUYD6f_OZ6-l7rg8duM-TeFLLnlVkN6dV_NC8vOVvTgrV0T2ALsyK8HqpJ-KkWD7VXBSDRfdSkMI_uj3kwXUulJquoUF2TVWFGrPNHn1hdtzCRvCnKb/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+28-+Table+Storage+creation+Powershell.png" /></a>
<br />
<br />
This is the table view in portal:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZAVdACfckqsby5emvrkCwyNjAaNup1x2Ggr7zexlBbEU4Q-xHu4LGn_mHqdfaXdGrcpxsH7vnIvYfahxg_8RzFvX8da43WDMqVIEW_nB1_nkZRAejuigCEB2DACMj0e-nToGoZoNcSzLD/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+29-+Table+Storage+creation+Portail.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZAVdACfckqsby5emvrkCwyNjAaNup1x2Ggr7zexlBbEU4Q-xHu4LGn_mHqdfaXdGrcpxsH7vnIvYfahxg_8RzFvX8da43WDMqVIEW_nB1_nkZRAejuigCEB2DACMj0e-nToGoZoNcSzLD/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+29-+Table+Storage+creation+Portail.png" /></a>
<br />
<br />
<h4>
5.4 Adding the Storage Account and the Storage Table variables to the Runbook</h4>
Now than we have the name of the Storage Account and the Storage Table we can pass them to the runbook
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;">
<span style="color: #7096ff;">
New-AzAutomationVariable</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Name <span style="color: #ce9178;">"storageAccountName"</span> -Encrypted <span style="color: #569cd6;">$False</span> -Value <span style="color: #9ad7fa;">$storageaccountname</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span>
<span style="color: #7096ff;">New-AzAutomationVariable</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Name <span style="color: #ce9178;">"tableName"</span> -Encrypted <span style="color: #569cd6;">$False</span> -Value <span style="color: #9ad7fa;">$tableName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span>
</pre>
<div class="h2-paragraph">
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-pereovk4yuMvYrJ38in6aBagHU4_XcHSU_UL056GlumDpQFHbcB7MlbpvIFJYXxjgmPggr5j05YsYU6YnDdmwALU0dOYo-yutdnd852xuRhUKSJoHumUQbKNY8Gm-ReUcKrhq5nFlcdD/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+43+-+adding+storage+variable+to+the+runbook+powershell.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-pereovk4yuMvYrJ38in6aBagHU4_XcHSU_UL056GlumDpQFHbcB7MlbpvIFJYXxjgmPggr5j05YsYU6YnDdmwALU0dOYo-yutdnd852xuRhUKSJoHumUQbKNY8Gm-ReUcKrhq5nFlcdD/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+43+-+adding+storage+variable+to+the+runbook+powershell.png" class="screenshot-standard"/></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7H_P38smxKKJrun4MIIDJTvhuHLLCEZp42kr2pCWtV5NzQazlneSudf17Reqky3Z-AS-6oTS2j4JRy_w0owgHA6vP0ozjQi7F_EyOEL0GFnYa4PriPdtRs43ifVGg0KrvEUMyptz6FtbM/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+44+-+adding+storage+variable+to+the+runbook+portal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7H_P38smxKKJrun4MIIDJTvhuHLLCEZp42kr2pCWtV5NzQazlneSudf17Reqky3Z-AS-6oTS2j4JRy_w0owgHA6vP0ozjQi7F_EyOEL0GFnYa4PriPdtRs43ifVGg0KrvEUMyptz6FtbM/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+44+-+adding+storage+variable+to+the+runbook+portal.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>
6. Runbook creation</h3>
Last resource to create, we will create the runbook while importing its code from my Gist :
<br />
You can see how the runbook code is:
<br />
<ul>
<li>Importing the AzureADPreview Powershell module</li>
<li> getting the credentials from the Automation Account</li>
<li>connecting to AzureAD</li>
<li>getting the Azure AD Audit Logs in 1 cmdlet</li>
<li>connecting then to the Azure tenant</li>
<li>retrieving the Azure Storage Table</li>
<li>create a line by AD log an store the log in it</li>
</ul>
<br />
<script src="https://gist.github.com/MarcCharmois/0054fc0e20f26afc3161d9397c16d083.js"></script>
Copy and paste the first line and replace by a path that exists in your loacl machine.
<br />
Then, copy and paste the other lines in your PowerShell window and hit enter.
<br />
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#Importing Runbook code from a public Gist</span>
<span style="color: #9ad7fa;">$runbookCodeFileTempPath</span> = <span style="color: #ce9178;">"C:\dev\"</span> <span style="color: #6a9955;">#set a path that really exists in your local machine</span>
<span style="color: #9ad7fa;">$runbookName</span> = <span style="color: #ce9178;">"exportAzureADAuditLogs"</span>
<span style="color: #9ad7fa;">$runbookCodeFileName</span> = <span style="color: #ce9178;">"Test-exportAzureadauditlogs.ps1'"</span>
<span style="color: #9ad7fa;">$runBookContentUri</span> = <span style="color: #ce9178;">"https://gist.githubusercontent.com/MarcCharmois/0054fc0e20f26afc3161d9397c16d083/raw/8ac0bf3a7d445aaba8a072c769591582acb83e9b/Store%2520Azure%2520AD%2520Audit%2520logs%2520Runbook%25201"</span>
<span style="color: #7096ff;">Invoke-WebRequest</span> -Uri <span style="color: #9ad7fa;">$runBookContentUri</span> -OutFile (<span style="color: #9ad7fa;">$runbookCodeFileTempPath</span> + <span style="color: #9ad7fa;">$runbookCodeFileName</span>)
<span style="color: #9ad7fa;">$params</span> = <span style="color: #569cd6;">@</span>{
<span style="color: #ce9178;">'Path'</span> = <span style="color: #9ad7fa;">$runbookCodeFileTempPath</span> + <span style="color: #9ad7fa;">$runbookCodeFileName</span>
<span style="color: #ce9178;">'Description'</span> = <span style="color: #ce9178;">'export Azure AD Audit logs in a Azure Storage Account Table'</span>
<span style="color: #ce9178;">'Name'</span> = <span style="color: #9ad7fa;">$runbookName</span>
<span style="color: #ce9178;">'Type'</span> = <span style="color: #ce9178;">'PowerShell'</span>
<span style="color: #ce9178;">'ResourceGroupName'</span> = <span style="color: #9ad7fa;">$resourceGroupName</span>
<span style="color: #ce9178;">'AutomationAccountName'</span> = <span style="color: #9ad7fa;">$automationAccountName</span>
<span style="color: #ce9178;">'Published'</span> = <span style="color: #569cd6;">$true</span>
}
<span style="color: #6a9955;">#New Runbook for the automation Account</span>
<span style="color: #7096ff;">Import-AzAutomationRunbook</span> <span style="color: #9ad7fa;">@params</span>
</pre>
<div class="h2-paragraph">
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEgNbsODl85hoOwas_yyrHsgi4Zu894fl1UsRG5yzBO0_L7A3jdAymS5eSVzapPrs6_m_eK6r_YkrAKckBfbLIUBbx7tOXQXz3Ky8v4uVqQBU4SkrB6iC09T0NEfiicKEu8n-UXoZHS0WC/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+29+-+Runbook+creation+PowerShell.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEgNbsODl85hoOwas_yyrHsgi4Zu894fl1UsRG5yzBO0_L7A3jdAymS5eSVzapPrs6_m_eK6r_YkrAKckBfbLIUBbx7tOXQXz3Ky8v4uVqQBU4SkrB6iC09T0NEfiicKEu8n-UXoZHS0WC/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+29+-+Runbook+creation+PowerShell.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn50dmiuw7b74SGjHmNCKUyy7kJHBwKFJ4wadLGoCwG5nlN6hhaVfwpEIvc0Ufw6YUMcHq8_wphZCRpUkOlFlT6WVeL-zR4HX8uoB5a1j91aC-ejPA32-jX0uJG7MiPvTzziAYrgDfVjWA/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+30+-+Runbook+creation+Portail.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn50dmiuw7b74SGjHmNCKUyy7kJHBwKFJ4wadLGoCwG5nlN6hhaVfwpEIvc0Ufw6YUMcHq8_wphZCRpUkOlFlT6WVeL-zR4HX8uoB5a1j91aC-ejPA32-jX0uJG7MiPvTzziAYrgDfVjWA/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+30+-+Runbook+creation+Portail.png" /></a>
<br />
<br />
<h3>
7. Starting the job, importing the logs, filling the table, reading output</h3>
For ending, we just have to start the job, wait for its completion and check remotely the output.
<br />
Just copy and paste the following code in your PowerShell window and hit enter.
<br />
<br />
</div>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: "consolas" , "courier new" , monospace; font-size: 14px; line-height: 1.2em; padding-left: 5px; white-space: pre;"><span style="color: #6a9955;">#Starting the Runbook Job</span>
<span style="color: #9ad7fa;">$job</span> = <span style="color: #7096ff;">Start-AzAutomationRunbook</span> -Name <span style="color: #9ad7fa;">$runbookName</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span>
<span style="color: #6a9955;"># Waiting for Job completion</span>
<span style="color: #9ad7fa;">$timeCount</span> = <span style="color: #b5cea8;">0</span>
<span style="color: white;">do</span> {
<span style="color: #6a9955;">#loop body instructions</span>
<span style="color: #7096ff;">Start-Sleep</span> -s <span style="color: #b5cea8;">1</span>
<span style="color: #9ad7fa;">$timeCount</span>++
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"waited "</span> + <span style="color: #9ad7fa;">$timeCount</span> + <span style="color: #ce9178;">" second(s)"</span>)
<span style="color: #9ad7fa;">$job2</span> = <span style="color: #7096ff;">Get-AzAutomationJob</span> -JobId <span style="color: #9ad7fa;">$job.JobId</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span>
<span style="color: white;">if</span> (<span style="color: #9ad7fa;">$job2.Status</span> -ne <span style="color: #ce9178;">"Completed"</span>) {
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"job status is "</span> + <span style="color: #9ad7fa;">$job2.Status</span> + <span style="color: #ce9178;">" and not completed"</span>)
}
<span style="color: white;">else</span> {
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"job status is "</span> + <span style="color: #9ad7fa;">$job2.Status</span> + <span style="color: #ce9178;">". Writing Job information and Output for checking..."</span>)
}
}<span style="color: white;">while</span> (<span style="color: #9ad7fa;">$job2.Status</span> -ne <span style="color: #ce9178;">"Completed"</span>)
<span style="color: #9ad7fa;">$job2</span> = <span style="color: #7096ff;">Get-AzAutomationJob</span> -JobId <span style="color: #9ad7fa;">$job.JobId</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span>
<span style="color: #9ad7fa;">$job2</span>
<span style="color: white;">if</span> (<span style="color: #9ad7fa;">$job2.Exception</span> -eq <span style="color: #569cd6;">$null</span>) {
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"job completed with no exceptions"</span>)
}
<span style="color: white;">else</span> {
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"job exceptions: "</span> + <span style="color: #9ad7fa;">$job2.Exception</span>)
}
<span style="color: #6a9955;"># Full Job output </span>
<span style="color: #9ad7fa;">$jobOutPut</span> = <span style="color: #7096ff;">Get-AzAutomationJobOutput</span> -AutomationAccountName <span style="color: #9ad7fa;">$automationAccountName</span> -Id <span style="color: #9ad7fa;">$job.JobId</span> -ResourceGroupName <span style="color: #9ad7fa;">$resourceGroupName</span> -Stream <span style="color: #ce9178;">"Any"</span> | <span style="color: #7096ff;">Get-AzAutomationJobOutputRecord</span>
<span style="color: #9ad7fa;">$jobOutPut</span> = (<span style="color: #9ad7fa;">$jobOutPut</span> | <span style="color: #7096ff;">ConvertTo-Json</span>) | <span style="color: #7096ff;">ConvertFrom-Json</span>
<span style="color: #9ad7fa;">$index</span> = <span style="color: #b5cea8;">0</span>
<span style="color: white;">foreach</span> (<span style="color: #9ad7fa;">$item</span> <span style="color: white;">in</span> <span style="color: #9ad7fa;">$jobOutPut</span>) {
<span style="color: #9ad7fa;">$index</span>++
<span style="color: #7096ff;">Write-Output</span> <span style="color: #ce9178;">"---------------------------------"</span>
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #ce9178;">"output "</span> + <span style="color: #9ad7fa;">$index</span>)
<span style="color: #7096ff;">Write-Output</span> (<span style="color: #9ad7fa;">$item.Value</span>)
}
</pre>
<div class="h2-paragraph">
<br />
You should obtain this :
<br />
<ul>
<li>
Job starting
</li>
<li>
Loop waiting for job completion
</li>
<li>
Output with the Azure Active Directory Audit Logs, and trace of the Azure Storage Table lines creation and filling.
</li>
</ul>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Lr1glFgy0Ji-D0y17IUzOoVJPgyrTjQcMq2R9mN6imxJSFvuX2Zc_hyv0HXGXEYnEdzo-h-gAV2HvGsQQ6fD3tEUwQly0chyyPC8FzEQKzRyawzB1No4YO79O7QKFwzHfl25bZPohyHY/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+30+-+starting+Job%252C+waiting.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Lr1glFgy0Ji-D0y17IUzOoVJPgyrTjQcMq2R9mN6imxJSFvuX2Zc_hyv0HXGXEYnEdzo-h-gAV2HvGsQQ6fD3tEUwQly0chyyPC8FzEQKzRyawzB1No4YO79O7QKFwzHfl25bZPohyHY/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+30+-+starting+Job%252C+waiting.png" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRavVH8txAwBWwVmr9P0RK92p59UIo1j0g4OlP5ERZitSO0Z8Mw4hnrc6UXLsEdT_MxteVJlcLTSFwm_3WYsaMxumInxDBhXZ9cAvBPzTCHm1r2FSV5sHDLtb9PUvW39RfOaN8tfDLMEXN/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+31+-+starting+Job%252C+waiting%252C+receiving+output.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRavVH8txAwBWwVmr9P0RK92p59UIo1j0g4OlP5ERZitSO0Z8Mw4hnrc6UXLsEdT_MxteVJlcLTSFwm_3WYsaMxumInxDBhXZ9cAvBPzTCHm1r2FSV5sHDLtb9PUvW39RfOaN8tfDLMEXN/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+31+-+starting+Job%252C+waiting%252C+receiving+output.png" /></a>
<br />
<br />
You can the go to the Azure Portal to check that:
<br />
a Runbook Job has been completed in the runbook
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpk_EAq6mtpMsHivX6FvLkrkIAhcZLm0lnCehZTA22M5hAshqSBSbbV7n7PNK83yrISiG7EPECMtR0Cm_3RO5evxcsRJ1UidQOXPa_qE0QCfqzIWXz6uz53IHyDJgLVlumk3fXpIQvYie5/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+32+-+Job+completed.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpk_EAq6mtpMsHivX6FvLkrkIAhcZLm0lnCehZTA22M5hAshqSBSbbV7n7PNK83yrISiG7EPECMtR0Cm_3RO5evxcsRJ1UidQOXPa_qE0QCfqzIWXz6uz53IHyDJgLVlumk3fXpIQvYie5/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+32+-+Job+completed.png" /></a>
<br />
<br />
retrieve the output you saw in the PowerShell window
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh49iTI7ivw24FbmMBmypy482A8O4d0M50PB7pyboXKN5czCoPlC3DLjlyZf32zuMZbDfx0Hj1HU9zUr0-mnvHoN9cRBa3yRhzB7jENi98nkB1_6Ag7GtfBas2dJRiMdUnA-D4-ujBRpi_k/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+33+-+Job+output.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh49iTI7ivw24FbmMBmypy482A8O4d0M50PB7pyboXKN5czCoPlC3DLjlyZf32zuMZbDfx0Hj1HU9zUr0-mnvHoN9cRBa3yRhzB7jENi98nkB1_6Ag7GtfBas2dJRiMdUnA-D4-ujBRpi_k/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+33+-+Job+output.png" /></a>
<br />
<br />
and most of all, check that the Azure Storage Table is successfully filled!
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7eHe3A3TUolUzXRIK9pTJoEZPIbZlksQHHXEnJs8dKxnJsuMze_CenvDdKCp0um4_NTKVPFmNc4jSYuTFnC_VNfMoKmTcgkpQyL3Gn_DITtWqButckpGdVcSvYbk-Ni7PFVqvGJdT48UT/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+34+-+Azure+Storage+Table+filled.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7eHe3A3TUolUzXRIK9pTJoEZPIbZlksQHHXEnJs8dKxnJsuMze_CenvDdKCp0um4_NTKVPFmNc4jSYuTFnC_VNfMoKmTcgkpQyL3Gn_DITtWqButckpGdVcSvYbk-Ni7PFVqvGJdT48UT/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+34+-+Azure+Storage+Table+filled.png" /></a>
<br />
<h2>
doing the same in one shot</h2>
You can find all this in one script in my GitHub repo: <a href="https://github.com/MarcCharmois/store-AzureAD-auditLogs-RunBook">store-AzureAD-auditLogs-RunBook</a>
<br />
If you want to execute that script in one shot, remove the resource group:
<br />
<pre>Remove-AzResourceGroup AzureADAuditLogs
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMvPVmkzTaavRoVUCkM4PwHq7VZBGgOrwkNc8Aj1gCMOVNawrwZKmuyWE1e4nOMiFWqTbxFJGquP8A8thRs_84VDR_FAd6Nu79xWCWpTfz0I5TnzPSA4a5iovBh-arzgf5GCVlBWw2euhZ/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+35+-+Removing+the+resource+group+name.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMvPVmkzTaavRoVUCkM4PwHq7VZBGgOrwkNc8Aj1gCMOVNawrwZKmuyWE1e4nOMiFWqTbxFJGquP8A8thRs_84VDR_FAd6Nu79xWCWpTfz0I5TnzPSA4a5iovBh-arzgf5GCVlBWw2euhZ/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+35+-+Removing+the+resource+group+name.png" /></a>
<br />
<br />
and play the script after having change the variable values at the begining of the script.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik1YtgHFYweblVJQ4oT5VsbCpvTpqfD6GtGb3YOdIcc1Z0NRAfUyR251KCx3k8OaTqlod0YEVLzEwF4GC2l9yW-2rnNjeZf8ezeQpsVWUiT3DTOhU8Coh65MqRivA6WSYaxHk70RG6IqAC/s1600/Store-ADLogs-Runbook-StorageAccount-Table+-+36+-+One+shot+action+in+one+script.png" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik1YtgHFYweblVJQ4oT5VsbCpvTpqfD6GtGb3YOdIcc1Z0NRAfUyR251KCx3k8OaTqlod0YEVLzEwF4GC2l9yW-2rnNjeZf8ezeQpsVWUiT3DTOhU8Coh65MqRivA6WSYaxHk70RG6IqAC/s1000/Store-ADLogs-Runbook-StorageAccount-Table+-+36+-+One+shot+action+in+one+script.png" /></a>
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-41431927248046422532019-08-29T16:11:00.000+02:002019-09-04T16:37:18.429+02:00Change Visual Studio Code syntax highlighting<style>
.code-line{
height:10px;
}
</style>
<div class="h2-paragraph">
This how-to shows how to change the syntax hilighting in Visual Studio code. This is the basic VS code PowerShell highlighting. I would have liked at least, a different color for the variables.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgsaLN4ViJnJCv2zY1zzJqQaq7_-ur8a3kqDJQNMY0yqbZlv_5R4Q1UIytj77PW_1As1LvwhWs_AdTWs0F6P5LlT1DXc6JDFKdnOumZMQLdXQ2_VSF-BssnZYe_LSFqaGmEVLjKm8GD29c/s1600/Visual-Studio-Code-Syntax-Highlighting+-+01+-+basic+PowerShell+syntax+highlight.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgsaLN4ViJnJCv2zY1zzJqQaq7_-ur8a3kqDJQNMY0yqbZlv_5R4Q1UIytj77PW_1As1LvwhWs_AdTWs0F6P5LlT1DXc6JDFKdnOumZMQLdXQ2_VSF-BssnZYe_LSFqaGmEVLjKm8GD29c/s1000/Visual-Studio-Code-Syntax-Highlighting+-+01+-+basic+PowerShell+syntax+highlight.png" class="screenshot-standard" /></a>
<br />
<br />
I wanted to use colorisers for the PowerShell variables. After few searches, I found the trick:
<br />
Open the settings of VS Code:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGRDFFXl4jkiUxYPHXdxmuYDP5K2o4tB2wdVtRISPKzz3hb5FQvV-1SMpcuOAhQeZhyphenhyphenGP6g2UicRuV7DTQVuVLXaS1Q_2WmJZPjaQ-NesEcNjJ2o-IoKdHkcT5AfKEhPpby2h4jOeN3ka9/s1600/Visual-Studio-Code-Syntax-Highlighting+-+03+-+open+settings.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGRDFFXl4jkiUxYPHXdxmuYDP5K2o4tB2wdVtRISPKzz3hb5FQvV-1SMpcuOAhQeZhyphenhyphenGP6g2UicRuV7DTQVuVLXaS1Q_2WmJZPjaQ-NesEcNjJ2o-IoKdHkcT5AfKEhPpby2h4jOeN3ka9/s1000/Visual-Studio-Code-Syntax-Highlighting+-+03+-+open+settings.png" class="screenshot-standard" /></a>
<br />
<br />
In Settings Editor, switch from "ui" to "json"
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJgxrvNJiYZwtSHBdHxTI3XpA8Lisw7AKizbLlDcyJ0nQ9DY730ZU8gyhDAuSVD_FGYCLp6pjbbYP6ZLc1OqtNwzuhaTzc-9Mt0aiSdByCDPzyC3LY55oftiTzr0J5O08274RPJGpy9W8Z/s1600/Visual-Studio-Code-Syntax-Highlighting+-+05+-+settings+editor+in+json+mode.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJgxrvNJiYZwtSHBdHxTI3XpA8Lisw7AKizbLlDcyJ0nQ9DY730ZU8gyhDAuSVD_FGYCLp6pjbbYP6ZLc1OqtNwzuhaTzc-9Mt0aiSdByCDPzyC3LY55oftiTzr0J5O08274RPJGpy9W8Z/s1000/Visual-Studio-Code-Syntax-Highlighting+-+05+-+settings+editor+in+json+mode.png" class="screenshot-standard" /></a>
<br />
<br />
This is the native parameters you should have after opening the settings of VS Code in json mode:
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkrjCMQQ8tYcQlPSLR6HcU7m0biyou9tPChN25ZEvd1Lyl7ZsFFtECjLghL2NCOjJCCZgJdzE2kpCaEJSuoJnuiMi78sncSLlXd6FI5FWdE-UAYHDSoqiOBeJg4uual-_8Gsep7YzrZOE3/s1600/Visual-Studio-Code-Syntax-Highlighting+-+07+-+settings.json+open.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkrjCMQQ8tYcQlPSLR6HcU7m0biyou9tPChN25ZEvd1Lyl7ZsFFtECjLghL2NCOjJCCZgJdzE2kpCaEJSuoJnuiMi78sncSLlXd6FI5FWdE-UAYHDSoqiOBeJg4uual-_8Gsep7YzrZOE3/s1000/Visual-Studio-Code-Syntax-Highlighting+-+07+-+settings.json+open.png" class="screenshot-standard" /></a>
<br />
<br />
This is the trick for changing the variable, the keywords (if, else, do, while, etc.) and the function (PowerShell cmdlets) color. Paste this without forgetting the coma to the existing text before pasting. You will put the color you like and will notice a tool for choosing the color you want. Awesome!
<br />
<br>
<pre class="code-standard" style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 1.2em; white-space: pre;padding:0;margin:0 0 0 10px;">
<span style="color: #9cdcfe;">"editor.tokenColorCustomizations"</span>: {
<span style="color: #9cdcfe;">"variables"</span>: <span style="color: #ce9178;">"#9ad7fa"</span>,
<span style="color: #9cdcfe;">"keywords"</span>: <span style="color: #ce9178;">"#fff"</span>,
<span style="color: #9cdcfe;">"functions"</span>: <span style="color: #ce9178;">"#7096ff"</span>
}
</pre>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3i8n4Lwhitc5vwUyXIn7H7CE7twTr43vi6fqKFBKO5mj2cv-NDwaveHNxKhJ9xXnfA47kos2b-HcTD784f98ncKir7udzMPs0oQw3h-3s1BsSqwNWXEROqUrsNbYIWE9el0vpq3TrI5sZ/s1600/Visual-Studio-Code-Syntax-Highlighting+-+09.+-+adding+editior.tokenColorCustomization.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3i8n4Lwhitc5vwUyXIn7H7CE7twTr43vi6fqKFBKO5mj2cv-NDwaveHNxKhJ9xXnfA47kos2b-HcTD784f98ncKir7udzMPs0oQw3h-3s1BsSqwNWXEROqUrsNbYIWE9el0vpq3TrI5sZ/s1000/Visual-Studio-Code-Syntax-Highlighting+-+09.+-+adding+editior.tokenColorCustomization.png" class="screenshot-standard" /></a>
<br>
<br>
This is the screenshot of my final config:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1KDIWC-WURLozGYV8X3hN6DxESPlzVYFiAGwLKmJoBmp9ovqd58eadbjnQKKwAdzaQlftmkNsbCXPgnhjUKr9Fbo3NqPs19q32-hPmM9WtDtYgEDHFPqTfLy-bFFv-yrGwK_BpyisBa3/s1600/Visual-Studio-Code-Syntax-Highlighting+-+11+-+final+settings+for+VS+Code+syntax+highlighting.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1KDIWC-WURLozGYV8X3hN6DxESPlzVYFiAGwLKmJoBmp9ovqd58eadbjnQKKwAdzaQlftmkNsbCXPgnhjUKr9Fbo3NqPs19q32-hPmM9WtDtYgEDHFPqTfLy-bFFv-yrGwK_BpyisBa3/s1000/Visual-Studio-Code-Syntax-Highlighting+-+11+-+final+settings+for+VS+Code+syntax+highlighting.png" class="screenshot-standard" /></a>
<br>
<br>
As soon as you save your settings.json file you can switch to an already open PowerShell source code file and enjoy the new syntax highlighting.
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQzF-MhG-WerquMM6e6cRL6IJW-EqjLFZpBPC4tutuK0Bcj00nD_qvDYF4UeFREhnFBKsMVW5VanqteO_PK1FZ0gjSp-5kr_7d6DF6P90at_jlyHvg7SwI6kiI8zvSdUw8uhvAQ_bjTr1d/s1600/Visual-Studio-Code-Syntax-Highlighting+-+13+-+syntax+highlighting+results.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQzF-MhG-WerquMM6e6cRL6IJW-EqjLFZpBPC4tutuK0Bcj00nD_qvDYF4UeFREhnFBKsMVW5VanqteO_PK1FZ0gjSp-5kr_7d6DF6P90at_jlyHvg7SwI6kiI8zvSdUw8uhvAQ_bjTr1d/s1000/Visual-Studio-Code-Syntax-Highlighting+-+13+-+syntax+highlighting+results.png" class="screenshot-standard" /></a>
<br>
<br>
Enjoy!
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-76317843286097208672019-08-29T14:50:00.002+02:002019-09-04T13:54:21.714+02:00Check list for configuring a local developement environment for Azure<div class="h2-paragraph">
As often, I am writing this post as a memo and also it can be useful to anybody.
<br>
As a Azure specialist contractor, I often go to a new client palce and receive a laptop to work on, from the client company. One first thing to do is often to configue the new Azure local environement to start working. Here is a check list of action to perform for working confortably:
<ul>
<li>Install Chocolatey (because you are sure to get secure software for windows from it, and that the installation process is simplified)</li>
<li>Install GitExtensions from Chocolatey (because it is a fine tool to mamage all the Git complexity when integrating an Azure devops team and most of all, you haven't to re-<i></i>authenticate for each push)</li>
<li>Install VS code</li>
</li>Configure VS Code for Azure Powershell (I like PowerShell ISE also, but with VS Code you can work on several files, change the syntaxic coloration,etc.) :
<ul>
<li>Install VS Code extension for PowerShell</li>
<li><a href="https://mosshowto.blogspot.com/2019/08/vs-code-syntax-highlighting.html">Configure VS code to get a good syntaxic coloration for PowerShell</a></li>
</ul>
</li>
<li>Install Azure Resource Manager Tools Extension for VS Code</li>
<li>Install Azure App Service Extension for VS Code</li>
</ul>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-65536028000860348122019-08-26T17:19:00.001+02:002019-09-04T13:59:23.746+02:00Get Azure AD audit and sign-in Logs using PowerShell and AzureADPreview moduleI ran randomly through a <a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-powershell-reporting">Microsoft documentation exposing PowerShell cmdlets to get quickly Azure AD logs</a>.
<br>As I had AzureAD module already installed on my computer, I tried to use them but they were not recongnized.
<br>
I understood that they, actually, were a part of another Azure AD PowerShell module: AzureADPreview.
<br>
<ul>
<li>
Here is the <a href="https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0">documentation for AzureAD PowerShell module</a>
</li>
<li>
Here is the <a href="https://docs.microsoft.com/en-us/powershell/azure/active-directory/overview?view=azureadps-2.0-preview">documentation for AzureADPreview powerShell module</a>
<br>
And the <a href="https://www.powershellgallery.com/packages/AzureADPreview/2.0.2.32">package installation link</a>
</li>
</ul>
It could be useful to use the module AzureADPreview to get quicly Azure AD Audit logs but you cannot run it if you have already the module AzureAD installed.
<br>
I had to uninstall the AzureAD module to have the AzureADPreview comdlets working as told in <a href="https://techcommunity.microsoft.com/t5/Azure-Active-Directory/Azure-AD-PowerShell-v2-cmdlets-not-working-e-g-Get-AzureADPolicy/m-p/87450">this forum</a>.
<br>Furthermore, it is, of course, not recommended by Microsoft to use the preview module for production matters.
<br>
<br>
Anyway, this is the steps to check in order to make the preview module work:
<br>
<h3>1. check there is only the AzureADPreview module installed and available</h3>
Use the
<pre>
Get-module -listavailable
</pre>
cmdlet to check that there is only the preview module available.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggM54gvZJldb8MMkHzlndQzVg_p7ojuZdMfHUXKwtiezrnThfAxEnVJcAStgXoJ3W80HUYxUPpNyBIe113_fYhHm5X1SlNS0v4_SFdKOChCDw2pJnKWc95JqwrO4VVMIkxsBf9-tC5IQwy/s1600/Azure-ADPreview-AuditLogs+-+01+-+checking+only+AzureADPreview+is+installed.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggM54gvZJldb8MMkHzlndQzVg_p7ojuZdMfHUXKwtiezrnThfAxEnVJcAStgXoJ3W80HUYxUPpNyBIe113_fYhHm5X1SlNS0v4_SFdKOChCDw2pJnKWc95JqwrO4VVMIkxsBf9-tC5IQwy/s1000/Azure-ADPreview-AuditLogs+-+01+-+checking+only+AzureADPreview+is+installed.png" class="screenshot-large" /></a>
<h3>2. connect to Azure AD</h3>
use the cmdlet
<pre>
connect-AzureAD
</pre>
If you have AzureAD module installed, the AzureAD module will be loaded and will perform the connection, thus you won't be able to use the AzureADPreview cmdlets later.
<br>That's why AzureAD module has to be uninstalled.
<br>You can see on my screenshot that neither AzureAD module nor AzureADPreview module have been loaded before the connection.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTi3zmvSThbAGKQQnpqnac-JThJLKUisuE7i2nNwLBe9qtfRn-Ub0JcONkYXA-Tf_S4zkt-1oMOE4_7wUBk80_Ey04PfG14t0O11Ba4sMthddPCuSQL-IX3JLpGicixTGvTNp2dYA6A9h/s1600/Azure-ADPreview-AuditLogs+-+03+-+connect-azuread.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTi3zmvSThbAGKQQnpqnac-JThJLKUisuE7i2nNwLBe9qtfRn-Ub0JcONkYXA-Tf_S4zkt-1oMOE4_7wUBk80_Ey04PfG14t0O11Ba4sMthddPCuSQL-IX3JLpGicixTGvTNp2dYA6A9h/s1000/Azure-ADPreview-AuditLogs+-+03+-+connect-azuread.png" class="screenshot-large" /></a>
<h3>3. Check that the module AzureADPreview has been loaded</h3>
To be sure that the Azure AD connection has been done by the AzureADPreview module, use the cmdlet:
<pre>
Get-Module
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSG74BEYz-v3gtUrGfdZeAOtazx-Eq5oC8rIa8TpiKeAML_pPiM-w8xG7vbvhxJbMznf96ISjJSxDrSvy79SN_DLxfx_hmNwyRAlIiWcrmB9QQLFHKkfAqPGQDDPc1aQtJ5pQwJ62GRG9t/s1600/Azure-ADPreview-AuditLogs+-+04+-+get-module+AzureADPreview.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSG74BEYz-v3gtUrGfdZeAOtazx-Eq5oC8rIa8TpiKeAML_pPiM-w8xG7vbvhxJbMznf96ISjJSxDrSvy79SN_DLxfx_hmNwyRAlIiWcrmB9QQLFHKkfAqPGQDDPc1aQtJ5pQwJ62GRG9t/s1000/Azure-ADPreview-AuditLogs+-+04+-+get-module+AzureADPreview.png" class="screenshot-large" /></a>
<br>
<br>
You can notice than AzureADPreview Module has been loaded and thus, that is actually that module that has connected the PowerShell session to Azure AD.
<h3>3. Get Azure AD Audit logs with a PowerShell cmdlet</h3>
use the cmdlet <a href="https://docs.microsoft.com/en-us/powershell/module/azuread/get-azureadauditdirectorylogs?view=azureadps-2.0-preview">Get-AzureADAuditDirectoryLogs</a> to get the Azure AD logs:
<pre>
get-azureadauditdirectorylogs
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjCoGueT7YIe13u0g21ZRAPjoo4H0l9kiTYdYLySwkmnMr0Axt_mOn8YyBQtbrUFtWF3cIWOlEsq5Ty_PyRTubjz0RXLPr4sbhdLTcM2YwP_Bo1T-TfOyPPgF2pr6Q4FDFpXd9T9CQTw3C/s1600/Azure-ADPreview-AuditLogs+-+05+-+get-azureadauditdirectorylogs.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjCoGueT7YIe13u0g21ZRAPjoo4H0l9kiTYdYLySwkmnMr0Axt_mOn8YyBQtbrUFtWF3cIWOlEsq5Ty_PyRTubjz0RXLPr4sbhdLTcM2YwP_Bo1T-TfOyPPgF2pr6Q4FDFpXd9T9CQTw3C/s1000/Azure-ADPreview-AuditLogs+-+05+-+get-azureadauditdirectorylogs.png" class="screenshot-large" /></a>
<br>
<br>
To get the Azure AD sign-ins logs you can use this cmdlet:
<pre>
Get-AzureADAuditSignInLogs
</pre>
However, you must have a premium subscritpion to Azure AD to be allowed to consult the sign-ins log.
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-16531972041328103382019-08-25T14:57:00.000+02:002019-09-10T11:42:35.440+02:00Request Graph in a PowerShell script to get Azure AD Logs<style>
.table1{
border-collapse:collapse;
width:80%;
}
.th1{
width:15%;
}
</style>
<div class="h2-paragraph">
<h2>Introduction</h2>
Azure Active Directory provides IT teams with two kinds of important reports (<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/concept-sign-ins">MS documentation</a>):
<ul>
<li>
<b>Audit logs</b>
<br>
These logs track all the activity regarding Azure Active directory performed by users and administrators.
<br>Audit logs provide system activity information about users and group management, managed applications and directory activities.
</li>
<li>
<b>Sign-ins</b>
<br>
These logs keep tracks of all the sign-ins to Azure. This is information about the usage of managed applications and user sign-in activities.
</li>
</ul>
This is the logs retention duration of all these logs in Azure Active Directory (<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-reports-data-retention">offical MS documentation here</a>)
<table class="table1">
<thead>
<tr>
<th style="text-align: left;">Report</th>
<th style="text-align: left;">Azure AD Free</th>
<th style="text-align: left;">Azure AD Basic</th>
<th style="text-align: left;">Azure AD Premium P1</th>
<th style="text-align: left;">Azure AD Premium P2</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">Audit logs</td>
<td style="text-align: left;">7 days</td>
<td style="text-align: left;">7 days</td>
<td style="text-align: left;">30 days</td>
<td style="text-align: left;">30 days</td>
</tr>
<tr>
<td style="text-align: left;">Sign-ins</td>
<td style="text-align: left;">N/A</td>
<td style="text-align: left;">N/A</td>
<td style="text-align: left;">30 days</td>
<td style="text-align: left;">30 days</td>
</tr>
<tr>
<td style="text-align: left;">Azure MFA usage</td>
<td style="text-align: left;">30 days</td>
<td style="text-align: left;">30 days</td>
<td style="text-align: left;">30 days</td>
<td style="text-align: left;">30 days</td>
</tr>
</tbody>
</table>
<br>
It is thus useful and sometimes mandatory (for very secure activities, Army, Health, Banks, etc.) to save these logs longer. Microsoft and Azure specialists offer several approaches to do it (<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/">MS Documentation 1</a> and <a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor">MS Documentation 2</a>).
<br>
You can manually:
<ul>
<li>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/quickstart-download-audit-report">Download reports</a>
</li>
<li>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/quickstart-install-power-bi-content-pack">Use power BI</a>
</li>
<li>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/quickstart-azure-monitor-route-logs-to-storage-account">Archive Azure AD logs to an Azure storage account</a>. This will store your logs in a blob format. Blobs are stored in nested folders: tenant, year, month, date, hour.
</li>
<li>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/tutorial-azure-monitor-stream-logs-to-event-hub#stream-logs-to-an-event-hub">Stream logs to an event hub</a>
</li>
<li>
<a href="https://blog.kloud.com.au/2019/05/21/azure-ad-log-analytics-kql-queries-via-api-with-powershell/">Link your Azure AD logs to a Log Analytics workspace</a>. This a temporary storage solution since you cannot keep the data in a log analytics workspace forever. Furthermore, even if you increase the retention duration (<a href="https://docs.microsoft.com/en-us/azure/azure-monitor/platform/manage-cost-storage#change-the-data-retention-period">it seems to be increasable to 730 days</a>) using log analytics workspace is somehow an expensive solution to store data.
</li>
</ul>
You can also use powershell scripts to get the data. You can then store them as file, in databases, or any storage solution either in your private cloud or in Azure. :
<ul>
<li>
<a href="https://blog.kloud.com.au/2019/05/21/azure-ad-log-analytics-kql-queries-via-api-with-powershell/">Link your Azure AD logs to a Log Analytics workspace and perform requests to the log analytics workspace using PowerShell</a>
</li>
<li>
<a href="https://mosshowto.blogspot.com/2019/08/azure-ad-logs-powershell-azureadpreview.html">Use the PowerShell module AzureADPreview to get the logs</a>. It is a preview module and it is not recommended to use it for production. Furthermore, this module is not compatible with the official AzureAD module. But it could be a good solution if you want to perform quick research in your Azure AD logs
</li>
<li>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/tutorial-access-api-with-certificates">Get data using the Azure Active Directory reporting API (Graph) and PowerShell with certificates</a>
</li>
<li>
<a href="https://blogs.aaddevsup.xyz/2019/05/azure-active-directory-reporting-api-with-ms-graph/">Use PowerShell to request the Graph API and get the logs data with an App (Service Principal) credentials</a>.
</li>
</ul>
In this post, I will detail the last approach. It is not the newest one, using the certificate seems to be the newest way to get the logs programmatically, and linking the log to a storage account the most simple way to save them, but this post will show you how to request the Graph API using PowerShell and the credentials of an Azure App (Service Principal). Thus, we will:
<ul>
<li>
Configure Azure to create an app and get the required App credentials to request the Graph API using PowerShell
</li>
<li>
Use the App client and secret to get the audit logs from Azure AD
</li>
</ul>
<h2>1. Configuration actions in Azure Portal to create the App</h2>
<a href="https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/howto-configure-prerequisites-for-reporting-api">Here is the official Microsoft documentation for reference</a>. Portal UI has changed and it is not up to date yet. That's a reason why I published this post.
<br>
<h3>1.1. Prerequisites</h3>
To register an App that can be used in PowerShell to get Azure AD logs, you have to be:
<ul>
<li>Azure Administrator</li>
<li>Global Administrator</li>
</ul>
<a href="https://docs.microsoft.com/en-us/azure/role-based-access-control/rbac-and-directory-admin-roles">Here is a documentation for main security and admin roles in Azure</a>
<h3>1.2. App creation</h3>
Sign in to Azure Portal and click on the active directory button in the left menu.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGU2v13TsymL_qZk9s2GHEfTCaTtKAt1hHCQurXknlr2SSffM2EgWRt2ZFu-Zvk69A6eSnC7ezC6rfMx_5wSsRxb4Jn-Pe5r5kYN8LdjqNDQwvc0VPWE4UCkwKljwsf9rm1fUB300lgNJK/s1600/Azure-AD-Logs-PowerShell-Graph+-+00+-+Azure+Portal+-+Active+Directory+access.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGU2v13TsymL_qZk9s2GHEfTCaTtKAt1hHCQurXknlr2SSffM2EgWRt2ZFu-Zvk69A6eSnC7ezC6rfMx_5wSsRxb4Jn-Pe5r5kYN8LdjqNDQwvc0VPWE4UCkwKljwsf9rm1fUB300lgNJK/s1000/Azure-AD-Logs-PowerShell-Graph+-+00+-+Azure+Portal+-+Active+Directory+access.png" class="screenshot-standard" /></a>
<br>
<br>
Then click on App Registration and Add.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkdf8tpX8kug0w4Ok8yeL1RdO41p9Z9y8ABx3sfpwBIxF0Yvky4XcOZWJbd-j3JLLANCb7ljndJNqBsVsU6RDGvUolfZlzGKnrmBn9_bNir_IifuNnzj1cZPWTVwwJyOobpKUpQIkQ1KL8/s1600/Azure-AD-Logs-PowerShell-Graph+-+01-Register+Application.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkdf8tpX8kug0w4Ok8yeL1RdO41p9Z9y8ABx3sfpwBIxF0Yvky4XcOZWJbd-j3JLLANCb7ljndJNqBsVsU6RDGvUolfZlzGKnrmBn9_bNir_IifuNnzj1cZPWTVwwJyOobpKUpQIkQ1KL8/s1000/Azure-AD-Logs-PowerShell-Graph+-+01-Register+Application.png" class="screenshot-standard" /></a>
<br>
<br>
In the "Register Application" pane, let default configuration. Just type the name of your App and for redirect url, you can use https://localhost.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx-9R7BPtdimnN_fkwfGLchAI_1B09cY7oPoqp6nQgPH_XwNDFGuvxHqzRO3vsEudS1Y8ki2OX34JfDMjSIyeHBJkNFQk5EgPgcMzCX1Z0CYqMgRFBTXLJUeNHmfUmlOJDoiapeQhU_Na4/s1600/Azure-AD-Logs-PowerShell-Graph+-+02+-Registering+Spn%252C++name%252C+type%252C+Url.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx-9R7BPtdimnN_fkwfGLchAI_1B09cY7oPoqp6nQgPH_XwNDFGuvxHqzRO3vsEudS1Y8ki2OX34JfDMjSIyeHBJkNFQk5EgPgcMzCX1Z0CYqMgRFBTXLJUeNHmfUmlOJDoiapeQhU_Na4/s1000/Azure-AD-Logs-PowerShell-Graph+-+02+-Registering+Spn%252C++name%252C+type%252C+Url.png" class="screenshot-standard" /></a>
<br>
<br>
When the App is registered, you are redirect on the App pane sumarizing main information. Notice that the Client ID has been defined.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRpotF81If48Xs5QfJFjyuDSY5WhpVeHSFAsgyT5KOaCWNY3_3ttnkDtk9rtK6AN54xqNWbdzYqW7gCJ7kg8-Q22wR9zI_sRZVP_IKsZcByMjNY8LoajW2a-0iMzgc3QzVEVgLZyLICdLq/s1600/Azure-AD-Logs-PowerShell-Graph+-+04+-+app+registered.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRpotF81If48Xs5QfJFjyuDSY5WhpVeHSFAsgyT5KOaCWNY3_3ttnkDtk9rtK6AN54xqNWbdzYqW7gCJ7kg8-Q22wR9zI_sRZVP_IKsZcByMjNY8LoajW2a-0iMzgc3QzVEVgLZyLICdLq/s1000/Azure-AD-Logs-PowerShell-Graph+-+04+-+app+registered.png" class="screenshot-standard" /></a>
<br>
<br>
<h3 id="GraphAuditLogReadAll">1.3. Setting permission Microsoft Graph AuditLog.ReadAll for the app</h3>
<br>
We are now going to give permissions to the App in order to be able to access the Azure AD Audit and Sign-ins logs data using the App credentials in a PowerShell script.
<br>
Click on the API Permission item on the left menu.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2gaUzmhErvRA5XH7-Af8g6V5bEI85lycigyYrwEWOuYBtcn5tEerFbjbitLUwCPfiZfBZgxEjn0WcjzLg8aGRhcakIHMge-tnUGcYbWcCp72KHi10xvhVAuUdrJ0O5aJ0rMhqM7nOdCkz/s1600/Azure-AD-Logs-PowerShell-Graph+-+06+-+permission.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2gaUzmhErvRA5XH7-Af8g6V5bEI85lycigyYrwEWOuYBtcn5tEerFbjbitLUwCPfiZfBZgxEjn0WcjzLg8aGRhcakIHMge-tnUGcYbWcCp72KHi10xvhVAuUdrJ0O5aJ0rMhqM7nOdCkz/s1600/Azure-AD-Logs-PowerShell-Graph+-+06+-+permission.png" class="screenshot-standard" /></a>
<br>
<br>
Then click on "Add a permission" button, the "Request API Permissions" pane is opening, click on the Microsoft Graph panel.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgahLgi_2_p_AlmxNMdYey9de_XsB_63VZTK9zuRFjK2XyYypaErIBAKLZ1phiL-5kyE2l9xWcygSQPczl7xifDb_fiJbDK_ZGftNiI6D3pn8CbLtWyRyegXg2S7HJiduuFHC-GK2vmeHzo/s1600/Azure-AD-Logs-PowerShell-Graph+-+08+-+adding+ms+graph+permission.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgahLgi_2_p_AlmxNMdYey9de_XsB_63VZTK9zuRFjK2XyYypaErIBAKLZ1phiL-5kyE2l9xWcygSQPczl7xifDb_fiJbDK_ZGftNiI6D3pn8CbLtWyRyegXg2S7HJiduuFHC-GK2vmeHzo/s1000/Azure-AD-Logs-PowerShell-Graph+-+08+-+adding+ms+graph+permission.png" class="screenshot-standard"/></a>
<br>
<br>
Click on Application permission because we want to use the App credentials and permission within a PowerShell script. Actually, we have registered an Azure App, but we are only interested by the Service Principal of the App (roughly a service account), because we need credentials and permissions for a PowerShell script. Here is the <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals">Microsoft documentation</a> about relationship between Azure App and Service Principal, if you want to know more on this topic.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY5OPuPrkGbPmWaH-x6aL8LEtisic8GCPenKCNFKAH4gW-NAirl6AeQOEK4DZDB_5kKX9ii_ByauDLXi2_lXNkWEjXRX3cfc-CvyvralXmIMxPwOpadRW5lqFyTjZOvkaGIPyDriEB4nSR/s1600/Azure-AD-Logs-PowerShell-Graph+-+10+-+ms+graph+permission%252C+application+permission.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY5OPuPrkGbPmWaH-x6aL8LEtisic8GCPenKCNFKAH4gW-NAirl6AeQOEK4DZDB_5kKX9ii_ByauDLXi2_lXNkWEjXRX3cfc-CvyvralXmIMxPwOpadRW5lqFyTjZOvkaGIPyDriEB4nSR/s1600/Azure-AD-Logs-PowerShell-Graph+-+10+-+ms+graph+permission%252C+application+permission.png" class="screenshot-standard" /></a>
<br>
<br>
Then, check AuditLog.ReadAll and click on "Add permissions" button.
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Cgi7-SxlvmC-IwQMbOXQmy-MhgPq6r2jrbx1sE3q4MC4JatFbw1Ll1L3XPQ2V5wEy5Em0Q-4CtqtDtWmLORrBwyUxomoz-xXAmIk-NgGfI3-bK2xRhnmDFXSWC58WJZu6dxMh6zwA5jU/s1600/Azure-AD-Logs-PowerShell-Graph+-+12+-+Ms+Graph+permission%252C+auditLog.readAll.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Cgi7-SxlvmC-IwQMbOXQmy-MhgPq6r2jrbx1sE3q4MC4JatFbw1Ll1L3XPQ2V5wEy5Em0Q-4CtqtDtWmLORrBwyUxomoz-xXAmIk-NgGfI3-bK2xRhnmDFXSWC58WJZu6dxMh6zwA5jU/s1000/Azure-AD-Logs-PowerShell-Graph+-+12+-+Ms+Graph+permission%252C+auditLog.readAll.png" class="screenshot-standard"/></a>
<br>
<br>
You are led back to the "API Permissions" pane and notice that the set permission needs Administrator aproval, so, as you are an administrator, click on "Add admin consent" button.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKn9Zrt7suvI-kfC3OP09QIR-PUoprG2UtuMmEtL5yN63_APVrqlA6vsqGV81sIvOUTYpROx8GRhaTvLmbJovCnc5UUAbp-QYfvTcByCeqjbSI-14D2SWhdfnfYm0klV5RJ5DsaqEp3TQG/s1600/Azure-AD-Logs-PowerShell-Graph+-+14+-+Permission+not+granted+by+admin.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKn9Zrt7suvI-kfC3OP09QIR-PUoprG2UtuMmEtL5yN63_APVrqlA6vsqGV81sIvOUTYpROx8GRhaTvLmbJovCnc5UUAbp-QYfvTcByCeqjbSI-14D2SWhdfnfYm0klV5RJ5DsaqEp3TQG/s1600/Azure-AD-Logs-PowerShell-Graph+-+14+-+Permission+not+granted+by+admin.png" class="screenshot-standard" /></a>
<br>
<br>
A confirmation dialog is opening beacause granting permissions to an App can have dangerous security consequences.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivV2H27rC_YdG0bbYuGyMLYvaQ7xgbWDh9rC7yyktWdhj9_DfSVDn899g65IIzSBVJCKvfSBLVtFJQrEmfkv8dmC7X-9R3_ihx1-R79v-0TtWp1QuEaNVughkZagY2LyNId51UIrHE1qkP/s1600/Azure-AD-Logs-PowerShell-Graph+-+16+-+grant+admin+consent+clicked.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivV2H27rC_YdG0bbYuGyMLYvaQ7xgbWDh9rC7yyktWdhj9_DfSVDn899g65IIzSBVJCKvfSBLVtFJQrEmfkv8dmC7X-9R3_ihx1-R79v-0TtWp1QuEaNVughkZagY2LyNId51UIrHE1qkP/s1000/Azure-AD-Logs-PowerShell-Graph+-+16+-+grant+admin+consent+clicked.png" class="screenshot-standard" /></a>
<br>
<br>
When admin consent is done you can see that the granted permission is effective.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlsNiUloV_yCGmZtjduTYDIQxNwGKd2c5_FuwV8-ZPM8D6ifdNOKqGIvkEnlvp2qW0oWpPremR0-wfBzIEFnL7H3p1N8psXP4aZFFlqyDZZQZc8q496u7YYFTCm3hWsRyUjUPIpmIsepmC/s1600/Azure-AD-Logs-PowerShell-Graph+-+18+-+grant+consent+confirmation+accrepted.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlsNiUloV_yCGmZtjduTYDIQxNwGKd2c5_FuwV8-ZPM8D6ifdNOKqGIvkEnlvp2qW0oWpPremR0-wfBzIEFnL7H3p1N8psXP4aZFFlqyDZZQZc8q496u7YYFTCm3hWsRyUjUPIpmIsepmC/s1600/Azure-AD-Logs-PowerShell-Graph+-+18+-+grant+consent+confirmation+accrepted.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>1.4. Setting permission Azure Active Directory Graph Directory.ReadAll for the app</h3>
Do exactly the same than above except...
<br>that you choose Azure Directory graph pane...
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwxuHV6hKYB13SsT4lLWWvuLDsO3-NpjyTOQtpnUC-hZNfRF-SpNJ_TI3saI7IR_RughFxrzFCiHdNmS9B_ckMfQ3nzoJZW0uMu8JpGpZ71yxaL0JlW4v8RTJS84rhqYUDtMqqSzNii65p/s1600/Azure-AD-Logs-PowerShell-Graph+-+20+-+Add+permission+Azure+AD+Graph.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwxuHV6hKYB13SsT4lLWWvuLDsO3-NpjyTOQtpnUC-hZNfRF-SpNJ_TI3saI7IR_RughFxrzFCiHdNmS9B_ckMfQ3nzoJZW0uMu8JpGpZ71yxaL0JlW4v8RTJS84rhqYUDtMqqSzNii65p/s1000/Azure-AD-Logs-PowerShell-Graph+-+20+-+Add+permission+Azure+AD+Graph.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOapBdrK2gKQqugzqG1rsdNT5CRPF3mZPVSqpTlnAIGN56SLGW8x9s87SxQdIqXIAZczR1lAT5-64v14gAXGUaJjXJr6yV5QfOTc85dkj1ADDCYmhOFh0bnzdcrHPVY-kwIcOZTxAuBYVZ/s1600/Azure-AD-Logs-PowerShell-Graph+-+22+add+permission+azure+ad+graph+select+application+permission.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOapBdrK2gKQqugzqG1rsdNT5CRPF3mZPVSqpTlnAIGN56SLGW8x9s87SxQdIqXIAZczR1lAT5-64v14gAXGUaJjXJr6yV5QfOTc85dkj1ADDCYmhOFh0bnzdcrHPVY-kwIcOZTxAuBYVZ/s1000/Azure-AD-Logs-PowerShell-Graph+-+22+add+permission+azure+ad+graph+select+application+permission.png" class="screenshot-standard" /></a>
<br>
<br>
and check Directory.ReadAll
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRryn64CFWPndsurK8Ps3QUf-rsykSsdegIzfOWlt3VYJNODQvEtYs8ONNQhqzUaeQ1Yi1zF6fPY67gaq3xF4hhgh_YV6XkeCMST3RqfY1k1YM0r7fUOh9l4fbeE6y_Lj2GSsVa_6O88D3/s1600/Azure-AD-Logs-PowerShell-Graph+-+24+-+add+permission+azure+ad+graph+directory.readAll+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRryn64CFWPndsurK8Ps3QUf-rsykSsdegIzfOWlt3VYJNODQvEtYs8ONNQhqzUaeQ1Yi1zF6fPY67gaq3xF4hhgh_YV6XkeCMST3RqfY1k1YM0r7fUOh9l4fbeE6y_Lj2GSsVa_6O88D3/s1600/Azure-AD-Logs-PowerShell-Graph+-+24+-+add+permission+azure+ad+graph+directory.readAll+.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP_EDJvQo5M1A0KWtO0c93P22KRu5kNJpOU3kvnGSrKIShG9GO3EC_EHfBg78xQWxYGnwPTFkIwkiWB5QE_6Gy4p98Rp72XQXwVuGwDCoTJYG_85HamlFGdRCnPEeTxOAX_KEbpPu5IDmS/s1600/Azure-AD-Logs-PowerShell-Graph+-+26+-+permission+directory.readAll+added+but+not+granted+by+admin.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP_EDJvQo5M1A0KWtO0c93P22KRu5kNJpOU3kvnGSrKIShG9GO3EC_EHfBg78xQWxYGnwPTFkIwkiWB5QE_6Gy4p98Rp72XQXwVuGwDCoTJYG_85HamlFGdRCnPEeTxOAX_KEbpPu5IDmS/s1000/Azure-AD-Logs-PowerShell-Graph+-+26+-+permission+directory.readAll+added+but+not+granted+by+admin.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjarMPTJ_n0fsSttriNABMMAV6PGPYrfc8Tev9xUlTK6VEMMOiSt0_GmelVzPf0kC71UHLQs8Pib-sIYHvgnnI0owWzn9ew80V2DClbs4PbgPkFOY1Voyj7ULajl-708B9FCH277cnaPcW5/s1600/Azure-AD-Logs-PowerShell-Graph+-+28+-+admin+consent+clicked+but+not+confirm.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjarMPTJ_n0fsSttriNABMMAV6PGPYrfc8Tev9xUlTK6VEMMOiSt0_GmelVzPf0kC71UHLQs8Pib-sIYHvgnnI0owWzn9ew80V2DClbs4PbgPkFOY1Voyj7ULajl-708B9FCH277cnaPcW5/s1000/Azure-AD-Logs-PowerShell-Graph+-+28+-+admin+consent+clicked+but+not+confirm.png" class="screenshot-standard" /></a>
<br>
<br>
You should obtain this screen at the end.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgEMvQzs5vfnP8FTa1ue5sJ6NqOrmkDB5MdBlkYL8Tq6xo1iLrdsxpkSm7VWj077NZ69IQqzm_r_uJlO3yTIfTESjVCJJcotUhufLQ4mHGuglJGyWcef3nX86WEYWUy8pKfI6WbljrF2I-/s1600/Azure-AD-Logs-PowerShell-Graph+-+30+-+all+permissions+added+and+admin+consents+granted.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgEMvQzs5vfnP8FTa1ue5sJ6NqOrmkDB5MdBlkYL8Tq6xo1iLrdsxpkSm7VWj077NZ69IQqzm_r_uJlO3yTIfTESjVCJJcotUhufLQ4mHGuglJGyWcef3nX86WEYWUy8pKfI6WbljrF2I-/s1600/Azure-AD-Logs-PowerShell-Graph+-+30+-+all+permissions+added+and+admin+consents+granted.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>1.4. Setting secret for the App (Service Principal)</h3>
Now than whe have the App with its Service Principal Client ID and the required permissions for requesting Azure Active Directory Logs, it misses just a secret (password) to authenticate to Azure in a PowerShell script.
<br>
Click on "Certificates & secrets" item on the left menu, then on "New secret" button.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvFHwS_Fl0HID2-e4M3OMVjUnIT1cHY-tl6XtYp4zUT7eqeRAB68XnX2Ov1ZTArIAS0pnEFJKh_CeLtcX132fJG9a8R4kXQayb4PsUKrZIut-YcsL_skM_FiAZNGcvwEMMm2JVKDeFtM6q/s1600/Azure-AD-Logs-PowerShell-Graph+-+32+-++certificate+and+secret%252C+new+client+secret.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvFHwS_Fl0HID2-e4M3OMVjUnIT1cHY-tl6XtYp4zUT7eqeRAB68XnX2Ov1ZTArIAS0pnEFJKh_CeLtcX132fJG9a8R4kXQayb4PsUKrZIut-YcsL_skM_FiAZNGcvwEMMm2JVKDeFtM6q/s1000/Azure-AD-Logs-PowerShell-Graph+-+32+-++certificate+and+secret%252C+new+client+secret.png" class="screenshot-standard" /></a>
<br>
<br>
Give the secret a name and a duration.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiySiU8OmRxkmcikiVSF7pmVn1sF9hgUlgVua7XEly4Co-OFWvPcrMbPAT9DxmKJfKskneOGD9Z80KPvEoj8lc8lA2RW_cYLQJrSRNNICUP779TgvpLTNQHA9x1a-kfnj5gpHHHPTEC4J7u/s1600/Azure-AD-Logs-PowerShell-Graph+-+34+-+certificate+and+secret%252C+new+client+secret%252C+name+and+duration.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiySiU8OmRxkmcikiVSF7pmVn1sF9hgUlgVua7XEly4Co-OFWvPcrMbPAT9DxmKJfKskneOGD9Z80KPvEoj8lc8lA2RW_cYLQJrSRNNICUP779TgvpLTNQHA9x1a-kfnj5gpHHHPTEC4J7u/s1000/Azure-AD-Logs-PowerShell-Graph+-+34+-+certificate+and+secret%252C+new+client+secret%252C+name+and+duration.png" class="screenshot-standard" /></a>
<br>
<br>
When it's done you get a new secret. Cautionously copy and paste it in a file because the secret will be unvisible on the portal later for security concerns.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZWeofyhMuHmYZPZIThAiFRC_PkObYEMdhTamU9mmAnTjSw9Z-myq4qzRXmu-tZbgbowXarfKmEK2r5avKHOktTRd4gLrt4BP-QsCvCPnGhV4gvgn-B0RQ5XN1Uyklz_M0PNo9lRYvzlWO/s1600/Azure-AD-Logs-PowerShell-Graph+-+36+new+secret+created.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZWeofyhMuHmYZPZIThAiFRC_PkObYEMdhTamU9mmAnTjSw9Z-myq4qzRXmu-tZbgbowXarfKmEK2r5avKHOktTRd4gLrt4BP-QsCvCPnGhV4gvgn-B0RQ5XN1Uyklz_M0PNo9lRYvzlWO/s1000/Azure-AD-Logs-PowerShell-Graph+-+36+new+secret+created.png" class="screenshot-standard" /></a>
<br>
<br>
At this point, you have all you need to make a PowerShell script work: the App (Service Principal) with an ID, a secret and required permissions.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFy3PH35Q1dCMp18jkVAcv4VikZq3vv9TrIO5zw0pWlCRCUPw8nMmTIudA2qHWNHnxMryxR424bcwuZY5S2kepc839UOV5hXv1JtjxAbUvr7zyNKxnM1_FwSV0WSeTmgLxvu4XZJxJrzR3/s1600/Azure-AD-Logs-PowerShell-Graph+-+38+app+created.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFy3PH35Q1dCMp18jkVAcv4VikZq3vv9TrIO5zw0pWlCRCUPw8nMmTIudA2qHWNHnxMryxR424bcwuZY5S2kepc839UOV5hXv1JtjxAbUvr7zyNKxnM1_FwSV0WSeTmgLxvu4XZJxJrzR3/s1600/Azure-AD-Logs-PowerShell-Graph+-+38+app+created.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>2. Requesting Azure AD Logs in PowerShell with the created App</h2>
Thanks to Bachoang, here is a github script ready to use:
<script src="https://gist.github.com/bachoang/0ce05bbc3ff4fcb51b3a61e0353c404e.js"></script>
<br>
Save the script in a ps1 file, open it with your favorite PowerShell editor.
<br>
Replace the client ID, client secret by those of the created App. Change the tenant domain name.
<br>I also updated the Url of Graph API line 20:
<br>
$url = "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\`$filter=eventTime gt $2daysago"
<br>
<br>
You can also update the file path line 26 if you want to get the Azure AD logs in a file in json format
<br>Last, the new secret format is no longer 44 characthers as writen line 3, but 32.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsd6gd3sKJtNSbDmYN6wpBYkDLlgU5Gwdu55GgafECUOi3qUDdCkDb2x44ha808_p_emVMqwAlWFIMk2A0IkO9UWwoxiiZ6yavVVowVWF-qvgCewjEVSbAqblayq70hYNc2Bi7oBkJbS6c/s1600/Azure-AD-Logs-PowerShell-Graph+-+39+editing+PowerShell+script+and+changing+cleint+ID%252C+Secret+and+tenant+domain+name.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsd6gd3sKJtNSbDmYN6wpBYkDLlgU5Gwdu55GgafECUOi3qUDdCkDb2x44ha808_p_emVMqwAlWFIMk2A0IkO9UWwoxiiZ6yavVVowVWF-qvgCewjEVSbAqblayq70hYNc2Bi7oBkJbS6c/s1000/Azure-AD-Logs-PowerShell-Graph+-+39+editing+PowerShell+script+and+changing+cleint+ID%252C+Secret+and+tenant+domain+name.png" class="screenshot-standard" /></a>
<br>
<br>
Then, you can run the script and see the results in your PowerShell editor output.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoYlr-nw5hI7R5mdsAGpGxlHE1M3m9GP-M6OJ4NBuwbUUyjPGdRd9_5D478_mh-ero1eIQTxP7iDunczbTXaqjgFOUBNU0cOHPi8NnN4i6uc03ag353gH_Tmn8RjxqZdEhJicQJ9NuSIHJ/s1600/Azure-AD-Logs-PowerShell-Graph+-+39+executing+PowerShell+script.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoYlr-nw5hI7R5mdsAGpGxlHE1M3m9GP-M6OJ4NBuwbUUyjPGdRd9_5D478_mh-ero1eIQTxP7iDunczbTXaqjgFOUBNU0cOHPi8NnN4i6uc03ag353gH_Tmn8RjxqZdEhJicQJ9NuSIHJ/s1000/Azure-AD-Logs-PowerShell-Graph+-+39+executing+PowerShell+script.png" class="screenshot-standard" /></a>
<h2>3. Using Graph Explorer</h2>
I will finish this post by showing a way to track issues when requesting Graph if needed. You can use <a href="https://developer.microsoft.com/en-us/graph/graph-explorer">Graph Explorer</a>.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH3Yxc1lWzn12g5FkAbYxGlvsNckHeY4LP9R9N66yp7aAiL7-eebwPmXVo4WwEJe_iyR_4sT8MXFrMFOClpVrtjYIy1Z2_DS8-h5jJJ5HWJG2W1GbYNp7e1tuGY4lfLUEpJLAbSDbzyXot/s1600/Azure-AD-Logs-PowerShell-Graph+-+40+testing+Graph+API+in+Graph+explorer.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH3Yxc1lWzn12g5FkAbYxGlvsNckHeY4LP9R9N66yp7aAiL7-eebwPmXVo4WwEJe_iyR_4sT8MXFrMFOClpVrtjYIy1Z2_DS8-h5jJJ5HWJG2W1GbYNp7e1tuGY4lfLUEpJLAbSDbzyXot/s1000/Azure-AD-Logs-PowerShell-Graph+-+40+testing+Graph+API+in+Graph+explorer.png" class="screenshot-standard" /></a>
<br>
<br>
Sign-in with your tenant admin account, paste the Graph Azure AD request and run the query. You can check that way that everything is all right regarding the Graph Url, an data availability and correctness.
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifqy9cXuniB3oSL5RTcf4SRgLwogyi5ESI4rAzq1Sw3rBazphVrxbh85GCbDryoGRm8WWPNaPnn3VGU1esIjMXLhVEIE02GOGLuCX6ZmkStSVlI3Nnd5BiK923EDDBBsdd44xHsvB1jGVM/s1600/Azure-AD-Logs-PowerShell-Graph+-+42+testing+Graph+API+in+Graph+explorer.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifqy9cXuniB3oSL5RTcf4SRgLwogyi5ESI4rAzq1Sw3rBazphVrxbh85GCbDryoGRm8WWPNaPnn3VGU1esIjMXLhVEIE02GOGLuCX6ZmkStSVlI3Nnd5BiK923EDDBBsdd44xHsvB1jGVM/s1000/Azure-AD-Logs-PowerShell-Graph+-+42+testing+Graph+API+in+Graph+explorer.png" class="screenshot-standard" /></a>
<br>
<br>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com2tag:blogger.com,1999:blog-4357140756496246910.post-34828064188268000802019-08-23T16:07:00.000+02:002019-09-04T16:46:34.110+02:00Check your Azure PowerShell Az Module Installation<div class="h2-paragraph">
You have at least 2 ways of using PowerShell for Azure:
<ul>
<Li>
Using the Azure Cloud Shell that is available within the Azure Portal
</li>
<li>
Executing locally on you machine PowerShell scripts or instruction into Windows 10 PowerShell Application, PowerShell ISE or Visual Studio Code. This is the most used way of driving Azure remotely in the large companies beacause you can create PowerShell scripts that can be saved in source code control solutions and reused.
</li>
</ul>
<br>
If you want to configure your PowerShell environment locally you should consider now to use PowerShell Az module since AzureRm has been deprecated since 2018 december.
<br>
There is plenty of posts explaining how to install Az module and to ensure the compatibility with AzureRm while it is not recommended to have both modules on your machine, but I didn't found much posts explaining how to check that your installation is successfull.
<br>
Thus, here are the steps to check to be sure that you really can use the complete Az module:
<br>
<br>
<h2>Get-InstalledModule</h2>
First, check that the installation links to the complete Az module with all dependencies:
<br>
<pre>
Get-InstalledModule
</pre>
You should have this result:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTx6C7Oq-IqQnV5TnkPHjidsBcB864dS9Z7LNe2AANSR8enmCrO8iElNiCzQNfHl2K4drOkh7n9ACNmSCGJONQ5KTCzTCiBstHwAtNrIcAECmg9Qdhu2J-Cmi7p6CxCxfD3CAh2_A1rxfl/s1600/check+Az+Module+Installation+-+01+-+Get-InstalledModule.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTx6C7Oq-IqQnV5TnkPHjidsBcB864dS9Z7LNe2AANSR8enmCrO8iElNiCzQNfHl2K4drOkh7n9ACNmSCGJONQ5KTCzTCiBstHwAtNrIcAECmg9Qdhu2J-Cmi7p6CxCxfD3CAh2_A1rxfl/s1000/check+Az+Module+Installation+-+01+-+Get-InstalledModule.png" data-original-width="1088" data-original-height="1027" class="screenshot-standard"/></a>
<br>
<h2>Get-Module -ListAvailable</h2>
Then, check that the module and the dependencies can be actually loaded in PowerShell by using:
<pre>
Get-Module -ListAvailable
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9TE3q4JOdBLgZqKQmIzDPlZ0FjkzWIETm01cpV_nBTnIh6YBT1qfbRt_3aXs_xv1H6_4Ra40PyxpoRVb_QjCWRAu2BPl1wYv7DbSL0SooLsE7vzhVNYo70FJs1S_amnwn6kgGWD45QECL/s1600/check+Az+Module+Installation+-+02+-+Get-Module+-listavailable+-+installation+complete.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9TE3q4JOdBLgZqKQmIzDPlZ0FjkzWIETm01cpV_nBTnIh6YBT1qfbRt_3aXs_xv1H6_4Ra40PyxpoRVb_QjCWRAu2BPl1wYv7DbSL0SooLsE7vzhVNYo70FJs1S_amnwn6kgGWD45QECL/s1000/check+Az+Module+Installation+-+02+-+Get-Module+-listavailable+-+installation+complete.png" data-original-width="1107" data-original-height="1037" class="screenshot-standard" /></a>
<br>
<br>
In a previous installation I have done, the installation was not complete:
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7y1273hGAHQ4oqPOeeVQFeEAGwuA0XjTyTB9ny_t8uyFiNAEbzaqFivwzewlq1voFqMWtXZMSKLCyiTa8ccD0fljILDqvuv30c750pr8ASZ5l_VK32cX4ecNpkxLFYm3f4gsUYnmiNnP/s1600/check+Az+Module+Installation+-+03+-+Get-Module+-listavailable+-+installation+not+complete.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7y1273hGAHQ4oqPOeeVQFeEAGwuA0XjTyTB9ny_t8uyFiNAEbzaqFivwzewlq1voFqMWtXZMSKLCyiTa8ccD0fljILDqvuv30c750pr8ASZ5l_VK32cX4ecNpkxLFYm3f4gsUYnmiNnP/s1000/check+Az+Module+Installation+-+03+-+Get-Module+-listavailable+-+installation+not+complete.png" data-original-width="1094" data-original-height="884" class="screenshot-standard" /></a>
<br>
<br>
Only the command Get-Module -ListAvailable will make you sure that you can actually use a module installed. I had to reinstall Az module by typing
<pre>
Install-Module -Name Az -AllowClobber
</pre>
(AllowClobber avoids conflicts with the previously already installed dependencies)
<br>
<h2>Get-Module</h2>
Regarding the command Get-Module, it shows you the modules currently loaded in your PowerShell tool.
<br>Exemple:
<br>If I execute the commad Get-module on a fresh PowerShell Window, I get this:
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVudavsjayz0Szey81ZR4-17EGDVrE4QGt-vwvNDqS9y952Y9lEGP2Ru0GlHk_lpk6dwNHmaTRiMbOtmQ6SEHOPVIvWqHBwnDNBGuVc-munqdy_oKtRCtbu-uNZiAQ8HgmkbRlBd3UEQyO/s1600/check+Az+Module+Installation+-+04+-+Get-Module++-+Before+using+Az.Resources.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVudavsjayz0Szey81ZR4-17EGDVrE4QGt-vwvNDqS9y952Y9lEGP2Ru0GlHk_lpk6dwNHmaTRiMbOtmQ6SEHOPVIvWqHBwnDNBGuVc-munqdy_oKtRCtbu-uNZiAQ8HgmkbRlBd3UEQyO/s1000/check+Az+Module+Installation+-+04+-+Get-Module++-+Before+using+Az.Resources.png" class="screenshot-standard" /></a>
<br>
Then, if I execute a search on Azure available locations by typing
<pre>
Get-AzLocation | Select Location
</pre>
and I reexecute Get-Module, I can see that the Az.Accounts and Az.Resources that are dependencies of the Az module have been loaded in my PowerShell application:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVlqe28m3pzsNn70h_QK6BxXO4WeXLFDwqoS1P6ifrpd5uLphVDqZrT3auX3RW0RCpoH3IAuyr7pLmGmUh0R2jRjgILdhJLuOWKDaqBNgddobhDdkvdWVrM9BVXt5FKJt1CL05rIyMImAU/s1600/check+Az+Module+Installation+-+05+-+Get-Module++-+after+using+Az.Resources.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVlqe28m3pzsNn70h_QK6BxXO4WeXLFDwqoS1P6ifrpd5uLphVDqZrT3auX3RW0RCpoH3IAuyr7pLmGmUh0R2jRjgILdhJLuOWKDaqBNgddobhDdkvdWVrM9BVXt5FKJt1CL05rIyMImAU/s1000/check+Az+Module+Installation+-+05+-+Get-Module++-+after+using+Az.Resources.png" class="screenshot-standard" /></a>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-22323670623936712712019-08-23T00:25:00.000+02:002019-09-04T16:51:58.435+02:00Create a user in Azure Active Directory using PowerShell (Windows 10)<div class="h2-paragraph">
I recently tried to create an user in Azure Active Directory using the Windows 10 PowerShell application and run through several issues, so I published this post to help people running through the same troubles.
<br>
<h2>Microsoft documentation reference : </h2>
<ul>
<li>
<a href="https://docs.microsoft.com/en-us/azure/role-based-access-control/tutorial-role-assignments-user-powershell">Tutorial: Grant a user access to Azure resources using RBAC and Azure PowerShell</a>
<br>The above link gives you an example of using PowerShell to create a user in Azure Active Diretory but it uses the Azure Cloud Shell. If you want to create a PowerShell script that you want to reuse from time to time to create users in Azure AD in a large company, using Azure Cloud Shell is not the best solution.
</li>
<li>
<a href="https://docs.microsoft.com/en-us/powershell/module/azuread/new-azureaduser?view=azureadps-2.0">New-AzureADUser</a>
<br>The above link gives you an example of using PowerShell to create a user in Azure Active Diretory but not explain the trick to configure your PowerShell environment properly to make it work.
</li>
</ul>
<h2>Tutorial</h2>
(tricks to create a user in Azure Active Directory using Windows 10 PowerShell Application)
<br>
<h2>1. Prerequisites</h2>
For doing this tutorial you need to have:
<ul>
<Li>
An Azure tenant
</li>
<li>
Permissions to create users in the Azure Active Directory of this tenant.
</li>
<li>
Azure PowerShell Az module installed
</li>
</ul>
<h2>2. Installation of AzureAD PowerShell Module</h2>
Open the Windows 10 PowerShell Application.
<br>
Type PowerShell in the Windows 10 pane and right click the Windows 10 PowerShell Application icon and open it "as Administrator"
<br>
<br>
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJDn6KFv1yG_9XNbr2qPfAjAxKj_cW8SvILo_LMoYGOlffWLABu5iobv2wFTYPeP3PW_2YBDyXGb_hQSIOJE5g11lowYQbGowS7Uk2cfnCntg-PuA6qDha9i-KV2bj29DlHGMgW3gy0XkT/s1600/Create+a+user+in+azure+AD+using+Powershell+-+01+-+opening+Windows+PowerShell+Application.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJDn6KFv1yG_9XNbr2qPfAjAxKj_cW8SvILo_LMoYGOlffWLABu5iobv2wFTYPeP3PW_2YBDyXGb_hQSIOJE5g11lowYQbGowS7Uk2cfnCntg-PuA6qDha9i-KV2bj29DlHGMgW3gy0XkT/s1600/Create+a+user+in+azure+AD+using+Powershell+-+01+-+opening+Windows+PowerShell+Application.png" style="width:300px"/></a>
<br>
<br>
In the PowerShell command type:
<br>
<pre>Install-Module AzureAD</pre>
to install the PowerShell Azure AD Module.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYzQitLMHa5kowDVUBpp4ipzY4xaQEkfk8m-QV2wJzAu4EQMZSimOgPBttInAY8qf1YcF7ufK8jxi6eeyevBf-8cEXnL-0HgtfcvZ5n87fxeMqfxpJoKiyBo6hWOvJMJlacpWN3w8fEIdZ/s1600/Create+a+user+in+azure+AD+using+Powershell+-+02+-+installing+PowerShell+module+AzureAD.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYzQitLMHa5kowDVUBpp4ipzY4xaQEkfk8m-QV2wJzAu4EQMZSimOgPBttInAY8qf1YcF7ufK8jxi6eeyevBf-8cEXnL-0HgtfcvZ5n87fxeMqfxpJoKiyBo6hWOvJMJlacpWN3w8fEIdZ/s1600/Create+a+user+in+azure+AD+using+Powershell+-+02+-+installing+PowerShell+module+AzureAD.png" class="screenshot-large"/></a>
<div style="clear:both"></div>
<br>
You can then check that the AzureAD Powershell Module has been installed successfully by typing the following command:
<br>
<pre>
Get-InstalledModule
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh42_HdLE8GzKG0Kj3OEkR-gHNhR4PjvLDnR97R3tlVzIGt-9H2DW7gD1ZFh8tp3LPcoxFa5sRom13QL-1ILMzZBsOZlwKLAVwvh-HBT2uwr1HVXp9BKniqrsLE-WB-7jhaXD1EKuutOhNr/s1600/Create+a+user+in+azure+AD+using+Powershell+-+05+-+using+get-installedmodule+cmdlet+to+check+the+AzureAD+PowerShell+Module+Installation_LI.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh42_HdLE8GzKG0Kj3OEkR-gHNhR4PjvLDnR97R3tlVzIGt-9H2DW7gD1ZFh8tp3LPcoxFa5sRom13QL-1ILMzZBsOZlwKLAVwvh-HBT2uwr1HVXp9BKniqrsLE-WB-7jhaXD1EKuutOhNr/s1600/Create+a+user+in+azure+AD+using+Powershell+-+05+-+using+get-installedmodule+cmdlet+to+check+the+AzureAD+PowerShell+Module+Installation_LI.jpg" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
and most of all that the module can be actually used:
<br>
<pre>
Get-Module -Listavailable
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGhyphenhyphenqb7X360Gmtm1W1OpRlPdQVafq2HTpGgRCm9HMQpprYdBR8VM1d2q0X1a6wDqOQzkE0eReizayYxace79TSUxMiYp4UaBWIcS6p2-V1f_s2LAfGfAYy14Ea7WtInJq_rqU7kGuurI8F/s1600/Create+a+user+in+azure+AD+using+Powershell+-+04+-+using+get-module+-listavailable+to+check+the+AzureAD+PowerShell+Module+Installation.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGhyphenhyphenqb7X360Gmtm1W1OpRlPdQVafq2HTpGgRCm9HMQpprYdBR8VM1d2q0X1a6wDqOQzkE0eReizayYxace79TSUxMiYp4UaBWIcS6p2-V1f_s2LAfGfAYy14Ea7WtInJq_rqU7kGuurI8F/s1600/Create+a+user+in+azure+AD+using+Powershell+-+04+-+using+get-module+-listavailable+to+check+the+AzureAD+PowerShell+Module+Installation.jpg" class="screenshot-large"/></a>
<div style="clear:both"></div>
<br>
then go to the directory where the module was installed to be able to copy the path and the name of the dll we need later.
<br>It should be:
<br>
C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.31\Microsoft.Open.AzureAD16.Graph.Client.dll
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-78nUEVGe547jaZ0Z-A0RVKmqVTj7pOKEmmZdZZIwgs1_sPLv8yVPT-VvjpVTZol-0Hmurw9ZzGXuNcnc6Ga15LBWcbf7VfRnzDr-wtZXfJs0Dfrz1R05LYaoPZu5jJUyWIS8PlVvfpiF/s1600/Create+a+user+in+azure+AD+using+Powershell+-+06+-+Checking+the+Azure+AD+needed+dll.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-78nUEVGe547jaZ0Z-A0RVKmqVTj7pOKEmmZdZZIwgs1_sPLv8yVPT-VvjpVTZol-0Hmurw9ZzGXuNcnc6Ga15LBWcbf7VfRnzDr-wtZXfJs0Dfrz1R05LYaoPZu5jJUyWIS8PlVvfpiF/s1600/Create+a+user+in+azure+AD+using+Powershell+-+06+-+Checking+the+Azure+AD+needed+dll.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
<h2>3. Loading the Microsoft.Open.AzureAD16.Graph.Client.dll within PowerShell Application. </h2>
Now, we have to load the dll within PowerShell. If we don't we will get an issue in PowerShell while trying to create the variable for the password of the user:
<pre>
New-Object : Cannot find type [Microsoft.Open.AzureAD.Model.PasswordProfile]: make sure
the assembly containing this type is loaded.
</pre>
So let's load the dll in PowerShell by typing the following instruction with the path copied previously:
<pre>
Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.31\Microsoft.Open.AzureAD16.Graph.Client.dll'
</pre>
<br>
<h2>4. Creating the user in Azure AD</h2>
Then let's create the password variable. You can use P@ssw0rd that is compliant to the required rules for an Azure AD password:
<pre>
$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = "P@ssw0rd"
</pre>
Then we have to connect to Azure AD in order to really create the user. Type:
<pre>
Connect-AzureAD
</pre>
A dialog is opening for you to type your Azure Account Login
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghQv3Q_1B4i65IS7xXPzDzl_dRBwzNcdM1LtkrZHh-FxxckYPXBljnPJPACbKq-izZaH926WPQOmyt9wqK5CH4G4BDtNIOh3BZ2f3vUm8x2ZX2GWA0JLKJC_PzKK4JK7wzT26hUj35S92e/s1600/Create+a+user+in+azure+AD+using+Powershell+-+07+-+connecting+to+Azure+AD+%25282%2529.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghQv3Q_1B4i65IS7xXPzDzl_dRBwzNcdM1LtkrZHh-FxxckYPXBljnPJPACbKq-izZaH926WPQOmyt9wqK5CH4G4BDtNIOh3BZ2f3vUm8x2ZX2GWA0JLKJC_PzKK4JK7wzT26hUj35S92e/s1600/Create+a+user+in+azure+AD+using+Powershell+-+07+-+connecting+to+Azure+AD+%25282%2529.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
then your Azure Account password
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcbOzHhusSEXz2IXlkJ7U76rf_JeEoxL2AFPOx6wjJ-2aa10_TU7zBBPcAGl4-1_P0CHKNj-CNqLN_s9PVWXM4b6Ndj_sJNPEL2sZ4ZzRWtia1jIJ4x-XzOhL7q3GdVIZF02b0Iy863Aqv/s1600/Create+a+user+in+azure+AD+using+Powershell+-+08+-+connecting+to+Azure+AD.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcbOzHhusSEXz2IXlkJ7U76rf_JeEoxL2AFPOx6wjJ-2aa10_TU7zBBPcAGl4-1_P0CHKNj-CNqLN_s9PVWXM4b6Ndj_sJNPEL2sZ4ZzRWtia1jIJ4x-XzOhL7q3GdVIZF02b0Iy863Aqv/s1600/Create+a+user+in+azure+AD+using+Powershell+-+08+-+connecting+to+Azure+AD.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
You should have the following screen after the connection:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2U6iYkHsGVPLT1_vuHS582DatBiTFAzPIft8Nl-CWG0gL7Ny2y4x9bet2HT3TYsmpKvTpxo4ccyCxVFj-cfsQkvIPE73zmVaTPo8d_srVlbFyRaEpyNhlt_BOC_shNliGqZNlCJgvrHm_/s1600/Create+a+user+in+azure+AD+using+Powershell+-+09+-+After+connectiong+to+Azure+AD+using+Windows+10+PowerShell+Application.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2U6iYkHsGVPLT1_vuHS582DatBiTFAzPIft8Nl-CWG0gL7Ny2y4x9bet2HT3TYsmpKvTpxo4ccyCxVFj-cfsQkvIPE73zmVaTPo8d_srVlbFyRaEpyNhlt_BOC_shNliGqZNlCJgvrHm_/s1000/Create+a+user+in+azure+AD+using+Powershell+-+09+-+After+connectiong+to+Azure+AD+using+Windows+10+PowerShell+Application.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
Then type the following line by replacing the tenant domain of the User Principal Name by your tenant domain (mine is charmoisdev.onmicrosoft.com):
<pre>
New-AzureADUser -DisplayName "RBAC Tutorial User2" -PasswordProfile $PasswordProfile `
-UserPrincipalName "rbacuser2@charmoisdev.onmicrosoft.com" -AccountEnabled $true -MailNickName "rbacuser2"
</pre>
You sould have the following screen after user creation:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaSxAO2ScjxZ9F2ZP1eIixei9NLIsbbKcZFszHQBsZ693HmFHnEB1N6sT3UvBl_nwDo_P_bSVFqbobTTyuRqOHN7lfoSOpxWW2nX3HIbTN8db4BYUoXNrHJTC7vbUSOcFb47hFcXsYatmZ/s1600/Create+a+user+in+azure+AD+using+Powershell+-+10+-+Creating+User+in+Azure+AD+using+Windows+10+PowerShell+Application.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaSxAO2ScjxZ9F2ZP1eIixei9NLIsbbKcZFszHQBsZ693HmFHnEB1N6sT3UvBl_nwDo_P_bSVFqbobTTyuRqOHN7lfoSOpxWW2nX3HIbTN8db4BYUoXNrHJTC7vbUSOcFb47hFcXsYatmZ/s1000/Create+a+user+in+azure+AD+using+Powershell+-+10+-+Creating+User+in+Azure+AD+using+Windows+10+PowerShell+Application.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
You can then check in the Azure Portal that your user has been created successfully:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQgAWnLeGk9HOrHLNfkXCfEb2S0mjgf5-76yFpNFUp7LteDD03nVd2S3Y8wwMmzTXyM5_FjthUO-PZj4Em-OBJt6xLDdp2W2exBczbewBtJMiDRBXque03GPxOwMUE0DTBKmVGLfv6Tw0w/s1600/Create+a+user+in+azure+AD+using+Powershell+-+11+-+Checking+in+Azure+Portal+thaht+user+is+well+created.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQgAWnLeGk9HOrHLNfkXCfEb2S0mjgf5-76yFpNFUp7LteDD03nVd2S3Y8wwMmzTXyM5_FjthUO-PZj4Em-OBJt6xLDdp2W2exBczbewBtJMiDRBXque03GPxOwMUE0DTBKmVGLfv6Tw0w/s1600/Create+a+user+in+azure+AD+using+Powershell+-+11+-+Checking+in+Azure+Portal+thaht+user+is+well+created.png" class="screenshot-large" /></a>
<div style="clear:both"></div>
<br>
<br>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com4tag:blogger.com,1999:blog-4357140756496246910.post-88386098113853327832017-10-22T09:51:00.003+02:002019-09-10T23:13:40.151+02:00Build a Node.js REST API with Swaggerize-express and deploy it to an Azure App Service (git push)<span style="color:red">updated 2019 sept. 10</span>
<h2>
Introduction</h2>
<div class="h2-paragraph">
In the 2 previous posts, I showed how to deploy a simple (just 2 GET actions) REST API based on Node.js, Express and <a href="https://www.npmjs.com/package/swaggerize-express">Swaggerize-express</a>:
<br />
<ul>
<li>
<a href="http://mosshowto.blogspot.fr/2017/10/try-azure-app-service.html">Very quicly by using the "Try Azure App Service" feature that let you play for free one hour with an Azure App Service</a>
</li>
<li>
<a href="http://mosshowto.blogspot.fr/2017/10/quick-tutorial-nodejs-app-service-azure.html">More professionnaly by using an Azure "free" account, one month available, but that requires you to give a credit card information to Microsoft.</a>
</li>
</ul>
I found the Node.js REST API in a Microsoft documentation, cleaned the code and pushed it in a <a href="https://github.com/MarcCharmois/app-service-api-node-contact-list">personal reporitory on Github</a>.
<br />
Now's time to show how to generate that code, and I use the word "generate" on purpose because we are going to see that the magic of swaggerize-express is to build a complete Node.js REST API in a few seconds based on the providing of a json template that describes the API. But most of all, this method to create an API allows you later, to be able to play with the API within Swagger UI.
<br> So let's do this now an end to end project:
<br>
<br>
<span style="background-color:yellow;font-weight:bold">starting the development of an API from scratch and finally deploying it into Azure so that it be available for anybody!</span>
<br />
<h3>Prerequisites</h3>
<ul>
<li>Node.js</li>
<li>Git</li>
<li>Visual Studio Code</li>
</ul>
All the references for installing all that, are in the beginning of my two previous posts.
<br />
<h2>Building the REST API</h2>
<h3>Installing Swaggerize-express</h3>
As described in the <a href="https://www.npmjs.com/package/swaggerize-express">Swaggerize-express documentation</a>, first, open a command prompt.
<br />
I navigated to my code repository and created a new folder for the project, then I installed swaggerize-express locally.
<br />
npm install -g yo
<br />
npm install -g generator-swaggerize
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaph9Fb-YIqB3HDTzLOkF3XoT6F4YXHu6JkaSjuZJpj7zGgrx22WvUZk2Q0U_XD4w0ymm_w8um1aGgCQYKPJCqS0rlW7XmcKZBBD7Ion75yJh6Fwhy3v4geKDgJ8H4ZhRnRe7UDqbiGbEb/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+01+installing+yeoman.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaph9Fb-YIqB3HDTzLOkF3XoT6F4YXHu6JkaSjuZJpj7zGgrx22WvUZk2Q0U_XD4w0ymm_w8um1aGgCQYKPJCqS0rlW7XmcKZBBD7Ion75yJh6Fwhy3v4geKDgJ8H4ZhRnRe7UDqbiGbEb/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+01+installing+yeoman.png" class="screenshot-standard" /></a>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRapFQLzF2BBwjm0DHd9GzO-9XfXfcpnoe32bXCJxAQ6P9j-dNplPOfeWq7HfEAfS3X_cl7gROUoL-Joz9RfRpJgDW8LQ9ARM7h3Y_SRGvD3EPu11IyStpbpys2DR8zini_7UUqoxGP7s/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+02+installing+swaggerize-express.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRapFQLzF2BBwjm0DHd9GzO-9XfXfcpnoe32bXCJxAQ6P9j-dNplPOfeWq7HfEAfS3X_cl7gROUoL-Joz9RfRpJgDW8LQ9ARM7h3Y_SRGvD3EPu11IyStpbpys2DR8zini_7UUqoxGP7s/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+02+installing+swaggerize-express.png" class="screenshot-standard" /></a>
<br />
<br />
As I had already swaggerize-express installed, it just updated my installed package.
<br />
<h3>Generating the REST API</h3>
Now we are going to generate a complete node.js REST API (although there is just 2 actions using GET verb) based on this descriptive json template. So copy next code (it is not a picture :-)):
<br>
<br>
<div class="code-standard">
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"swagger"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"2.0"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"info"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"version"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"v1"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"title"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"Contact List"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"description"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"A Contact list API based on Swagger and built
using Node.js"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">},</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"paths"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"/contacts"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"get"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"tags"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: [</span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"Contacts"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"operationId"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"contacts_get"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"consumes"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:[],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"produces"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:[</span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"application/json"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"text/json"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"responses"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"200"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"description"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:</span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"OK"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"schema"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"array"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"items"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"$ref"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"#/definitions/Contact"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"deprecated"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #569cd6; font-family: "consolas"; font-size: 8.5pt;">false</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"/contacts/{id}"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"get"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"tags"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: [</span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"Contacts"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"operationId"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"contacts_getById"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"consumes"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:[],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"produces"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:[</span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"application/json"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"text/json"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"parameters"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:[{</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"name"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">:</span><span style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"id"</span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"in"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"path"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"required"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #569cd6; font-family: "consolas"; font-size: 8.5pt;">true</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"integer"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"format"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"int32"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }],</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"responses"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"200"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"description"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"OK"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"schema"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"array"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"items"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"$ref"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"#/definitions/Contact"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"deprecated"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #569cd6; font-family: "consolas"; font-size: 8.5pt;">false</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"definitions"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"Contact"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"object"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"properties"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"id"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"format"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"int32"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">,</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"integer"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"name"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"string"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> },</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"email"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: {</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span lang="EN-US" style="color: #9cdcfe; font-family: "consolas"; font-size: 8.5pt;">"type"</span><span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">: </span><span lang="EN-US" style="color: #ce9178; font-family: "consolas"; font-size: 8.5pt;">"string"</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span lang="EN-US" style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> </span><span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">}</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;"> }</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: "consolas"; font-size: 8.5pt;">}</span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
</div>
</div>
<br>
Create a subfolder in your project folder. It is important to name it "config"
<br>Open the main project folder with Visual Studio Code
<br>Create an api.json empty file in the "config" sub-folder within Visual Studio Code
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEK7vOAJwC7Tpgob1ZuCZWc08MC7VYf8zjoqmmUoA6YlOzN4nPYgeuYv3DtiO3QrIjlQtvNDCkkWha-J2w6mW_rFAC8Qfg0XbMkErBUBZs7HJzIv88P6BhhHlN-ULJtuSHRGUCsAmw-lHD/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+03+creating+the+api.json+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEK7vOAJwC7Tpgob1ZuCZWc08MC7VYf8zjoqmmUoA6YlOzN4nPYgeuYv3DtiO3QrIjlQtvNDCkkWha-J2w6mW_rFAC8Qfg0XbMkErBUBZs7HJzIv88P6BhhHlN-ULJtuSHRGUCsAmw-lHD/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+03+creating+the+api.json+file.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmMif21FnSlaExAg9u5B-MOG7wDIJPCz3OooayNXFAocZDb8L6BMc8VTVXOM5aDkfBu4A_kJgpkgAV3gcULYcJTOd1Fo30K9fhjD5tjP6Wa2pFdZJgm1wNJpR-fDmU5fMFRYBqWVBII2PU/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+04+creating+the+api.json+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmMif21FnSlaExAg9u5B-MOG7wDIJPCz3OooayNXFAocZDb8L6BMc8VTVXOM5aDkfBu4A_kJgpkgAV3gcULYcJTOd1Fo30K9fhjD5tjP6Wa2pFdZJgm1wNJpR-fDmU5fMFRYBqWVBII2PU/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+04+creating+the+api.json+file.png" class="screenshot-standard" /></a>
<br>
<br>
<br>Paste the template json code in it and save it
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdylNGaHFAt5hYLt19kpFzQIVRq_w-mbPvXkEN2MzCFgzqEbtxjLUf6rHTUF2lAmahsX4YgzfQ1LiZxQ_q51xwIXcntVucirlPZOfKvYAwlqN8onYGj-Bx0KvVWOrDHkcuOtUFhoq7k9lr/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+05+copying+code+into+the+api.json+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdylNGaHFAt5hYLt19kpFzQIVRq_w-mbPvXkEN2MzCFgzqEbtxjLUf6rHTUF2lAmahsX4YgzfQ1LiZxQ_q51xwIXcntVucirlPZOfKvYAwlqN8onYGj-Bx0KvVWOrDHkcuOtUFhoq7k9lr/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+05+copying+code+into+the+api.json+file.png" class="screenshot-standard" /></a>
<br>
<br>
We can now generate the REST API.
<br>
Go back to your command prompt and type:
<br>
yo swaggerize
<br>
Follow the prompts (note: make sure to choose express as your framework choice).
<br>
When asked for a swagger document, give the complete path of your api.json file. In my case
<br>
C:\dev\vscode-repo\swaggerize-express-rest-api\config\api.json
<br>
Then the magic is starting and Swaggerize-express creates a complete REST API project.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkHWjM4afDzQ8J-IRF5EtqISJKd41JR9bsc2aqHOra06WVMz7w5yTAKAjW__f4orqN02yRyPL2biDy0Ich6MmMreBFMQ3AwU9Xz_-KfQmqlplQeGQeeMacL_D24-vzWp5D4DVNh0HbJKlx/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+06+swaggerize+is+creating+the+API.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkHWjM4afDzQ8J-IRF5EtqISJKd41JR9bsc2aqHOra06WVMz7w5yTAKAjW__f4orqN02yRyPL2biDy0Ich6MmMreBFMQ3AwU9Xz_-KfQmqlplQeGQeeMacL_D24-vzWp5D4DVNh0HbJKlx/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+06+swaggerize+is+creating+the+API.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTo5wX5xkDUCs2rdG23HH-4VjNftYtUP-msGIlDRCEXqRxiu2FCQYLlIMVwfKD2w2Km3ObB8vDLjF83fuFz4Rk3RsOJwPi5VZzI7Z_I0h0bnWR43cQxuRK48O33b6a7ZrqBtF1QZ5Weud/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+07+REST+API+created+by+swaggerize.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTo5wX5xkDUCs2rdG23HH-4VjNftYtUP-msGIlDRCEXqRxiu2FCQYLlIMVwfKD2w2Km3ObB8vDLjF83fuFz4Rk3RsOJwPi5VZzI7Z_I0h0bnWR43cQxuRK48O33b6a7ZrqBtF1QZ5Weud/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+07+REST+API+created+by+swaggerize.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipoURiMdq11AcmW2bV7YcSZpiK5KLhZk4l6NsuX2dTn6af74WhD-LX_siY_OVpxxmiE3PIameZORpL4XIdIgyQCs6Mr-81W1ksxRNBeHmTQPT9346NfHuSGbnvXSzPOa4OSTiy0NPP6Q1t/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+08+REST+API+created+by+swaggerize.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipoURiMdq11AcmW2bV7YcSZpiK5KLhZk4l6NsuX2dTn6af74WhD-LX_siY_OVpxxmiE3PIameZORpL4XIdIgyQCs6Mr-81W1ksxRNBeHmTQPT9346NfHuSGbnvXSzPOa4OSTiy0NPP6Q1t/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+08+REST+API+created+by+swaggerize.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Testing the first version of our REST API generated with Swaggerize-express</h3>
and we can test it right now by typing:
<br>
node server.js
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4wXUTSL2yam2y69AkhLsXJ8-Yh8RocyVa3uJn1_1BB6hBpvYqX_HpZUJMBniZOVf8rAjQ6SBAJXjUsBmMfuyFkgRrnMfwmrZeVktDMUYZ69adr_usPO4Yl4adeI_uc2AX5NUeM8JPWiM5/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+09+testing+REST+API+created+by+swaggerize.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4wXUTSL2yam2y69AkhLsXJ8-Yh8RocyVa3uJn1_1BB6hBpvYqX_HpZUJMBniZOVf8rAjQ6SBAJXjUsBmMfuyFkgRrnMfwmrZeVktDMUYZ69adr_usPO4Yl4adeI_uc2AX5NUeM8JPWiM5/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+09+testing+REST+API+created+by+swaggerize.png" class="screenshot-standard" /></a>
<br>
<br>
and hitting the API within Chrome to have the json display in the browser, as defined in the server.js file:
<br>
http://localhost:8000/contacts
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNIAUNoOgZnBJ9DPGBnWYU9n13sxO4ZWjTEJZqgu7jCFZedtGx3nnw2zOUBI5mUrjbmxRiVtRl0p1s0TVEMRjAKv2nAbGuhyWZv1oyPwBLfKLtwRitRq1geaEHST0DrMwOZv45X6CjNCPb/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+10+testing+REST+API+created+by+swaggerize.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNIAUNoOgZnBJ9DPGBnWYU9n13sxO4ZWjTEJZqgu7jCFZedtGx3nnw2zOUBI5mUrjbmxRiVtRl0p1s0TVEMRjAKv2nAbGuhyWZv1oyPwBLfKLtwRitRq1geaEHST0DrMwOZv45X6CjNCPb/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+10+testing+REST+API+created+by+swaggerize.png" class="screenshot-standard" /></a>
<br>
<br>
A mocked data generator is integrated with swaggerize-express that allows to test the API right after its creation.
<br>
Next step we are going to adapt this first project into an API with real data, and modify it to make it work within an Azure App Service.
<br>
<h2>Placing real (mock) data in the API</h2>
<h3>Understanding the code</h3>
Let's try to understand how the API works.
<br>
All the calls go first to sever.js, so let's open it.
We see this code:
<pre class="code-standard">
App.use(Swaggerize({
api: Path.resolve('./config/swagger.json'),
handlers: Path.resolve('./handlers')
}));
</pre>
So the calls to the API are driven by the handlers.
<br>
<ul>
<li>
If we hit the API url/contacts, the handlers\contacts.js file is processing the call.
</li>
<li>
If we hit the API url/contacts/anId, the handlers\contacts\{id}.js file is processing the call.
</li>
</ul>
So let's open first the handlers\contacts.js file to see how it is processing the call. Doing that we learn that it is redirecting the call to data\contact.js.
<br>
So let's open this file too. We see that at this location that the mock data is generated by the swaggerize mock data generator and it is said that is the place to connect with our real datas.
<br>
We are going to go up from the data source toward the handlers and to develop the capability of our REST API to send our data.
<h3>Adding the contacts.json file hosting our mock data</h3>
Let's create a contacts.json file under the data folder and place this json data in it:
<pre class="code-standard">
[
{
"id":1,
"name":"Barney Poland",
"email":"barney@contoso.com"
},
{
"id":2,
"name":"Lacy Barrera",
"email":"lacy@contoso.com"
},
{
"id":3,
"name":"Lora Riggs",
"email":"lora@contoso.com"
}
]
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGHeg1qUYh9nG1VmHIalb1oX8rbU4GQJsWTuAmHfJ1yae2zTB7m9zg5jaDhrk184z7Ufp7DRjOISeElZAf5ICoF9gTlCqKid_FPnfGyKYwkXSPoCFV6_Aa92snVpX5waYK_yMMmNn625v/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+11+adding+contacts.json+into+the+Rest+Api.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGHeg1qUYh9nG1VmHIalb1oX8rbU4GQJsWTuAmHfJ1yae2zTB7m9zg5jaDhrk184z7Ufp7DRjOISeElZAf5ICoF9gTlCqKid_FPnfGyKYwkXSPoCFV6_Aa92snVpX5waYK_yMMmNn625v/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+11+adding+contacts.json+into+the+Rest+Api.png" class="screenshot-standard"/></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3J-EWhDVBK8rLEgRwY3j5effdXAZeZJY0hbf3ujb4QLBG3jdcQNfKgoXidhyphenhyphenmPxDDVxtWWT6IfTiZ4hnInelk1zcWdeV2Ikl79WZ3ZQvW1oGKJQ-lEMRhcWm1IkARCNG1uUTLFB7Qntj/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+12+adding+contacts.json+into+the+Rest+Api.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3J-EWhDVBK8rLEgRwY3j5effdXAZeZJY0hbf3ujb4QLBG3jdcQNfKgoXidhyphenhyphenmPxDDVxtWWT6IfTiZ4hnInelk1zcWdeV2Ikl79WZ3ZQvW1oGKJQ-lEMRhcWm1IkARCNG1uUTLFB7Qntj/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+12+adding+contacts.json+into+the+Rest+Api.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Adding the contactsDataHandler.js file for serving our mock data</h3>
Rename the \data\contacts.js file to contactsDataHandler.js and add this code in it:
<pre class="code-standard">
'use strict';
var contacts = require('./contacts.json');
module.exports = {
all: function () {
return contacts;
}
};
</pre>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG3EyyQXFS6is7oY_yfTA98eXMWcAY1-PqsbM8UgzmJl3nWLs2e8XWl5CzEYhoQdzq7dgi9RXxxepGU5HhygpHcymSJLaAz4N0i8_Uy3ydlIXH49n5AO99sDLpdkDp9mprtpnrGSkXP_LH/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+13+adding+contactsDataHandler.js+into+the+Rest+Api.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG3EyyQXFS6is7oY_yfTA98eXMWcAY1-PqsbM8UgzmJl3nWLs2e8XWl5CzEYhoQdzq7dgi9RXxxepGU5HhygpHcymSJLaAz4N0i8_Uy3ydlIXH49n5AO99sDLpdkDp9mprtpnrGSkXP_LH/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+13+adding+contactsDataHandler.js+into+the+Rest+Api.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Updating the code in handler\contacts.js file for serving our mock full data</h3>
Then, replace the code of the handlers\contacts.js file (a kind of controller) by this one:
<pre class="code-standard">
'use strict';
var contactsDataHandler = require('../data/contactsDataHandler');
module.exports = {
get: function contacts_get(req, res) {
res.json(contactsDataHandler.all())
}
};
</pre>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyquOgh37c008NCAmtj2HfSZHSkvt1OXMw69bekHmn-r7vvtLgvaAquFH5Q5irhIGppF3l8aFI-8qkCphA7ZMKY012dx_UsQGJJ6KmTQWBTOP7RL1NoSDP77Vddb6nYNdzNHI_dyPxcj4g/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+14+changing+code+of+contacts.js+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyquOgh37c008NCAmtj2HfSZHSkvt1OXMw69bekHmn-r7vvtLgvaAquFH5Q5irhIGppF3l8aFI-8qkCphA7ZMKY012dx_UsQGJJ6KmTQWBTOP7RL1NoSDP77Vddb6nYNdzNHI_dyPxcj4g/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+14+changing+code+of+contacts.js+file.png" class="screenshot-standard" /></a>
<br>
<br>
Open a command prompt, navigate to your project folder and launch the server by typing:
<br>
node server.js
<br>
(for newbies, to stop the server on Windows type "ctrl c" like if you want to copy something)
<br>
At this step, as the js code is compiled by node.js before launching the server, if you had made a big coding error, the server wouldn't have started and you would have been provided within the command prompt with a error message with all the stack.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPhM6aOvBDrqW2qR0fn3JMs-FREeLpFNE3OzdRQfNFJSaq98_YAoGCtfxp5JhH-Fe5Ucoa2ryAy0qzAw9iwMlthtY3cjkfU-NjL7lHMcugAybdjlBNbJgJXLS7hixnB0Z-Ukj9FJFMSiUf/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+15+launching+the+server+for+testing.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPhM6aOvBDrqW2qR0fn3JMs-FREeLpFNE3OzdRQfNFJSaq98_YAoGCtfxp5JhH-Fe5Ucoa2ryAy0qzAw9iwMlthtY3cjkfU-NjL7lHMcugAybdjlBNbJgJXLS7hixnB0Z-Ukj9FJFMSiUf/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+15+launching+the+server+for+testing.png" class="screenshot-standard" /></a>
<br>
<br>
Then, hit localhost:8000/contacts on any browser but Internet Explorer (that serves the json as a file so not very useful for testing)
<br>Hurrah! We can see our real data sent back from the REST API for the first time!
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYAFC3m9UNxEywPq2vOGFgZXPEk2PZB9FwdkUF7-rN6XYNNKHRPJXdGrWpb-zEb4nQJBX-XpC6R-Li-ZzOwJN3mctIRNUcREvWjnK1c2YB7Tg8fWPBo8lkquBxBtWdGmDQ-wMLkoKAW07I/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+16+launching+the+browser+for+testing.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYAFC3m9UNxEywPq2vOGFgZXPEk2PZB9FwdkUF7-rN6XYNNKHRPJXdGrWpb-zEb4nQJBX-XpC6R-Li-ZzOwJN3mctIRNUcREvWjnK1c2YB7Tg8fWPBo8lkquBxBtWdGmDQ-wMLkoKAW07I/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+16+launching+the+browser+for+testing.png" class="screenshot-standard" /></a>
<br>
<br>
We didn't break the feature for requesting a single contact by its id. It's still working with auto-generated swaggerize mock data.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm7EyR7meFXf9LTUxEp51rXm0LivX-CI6jSJBtGjgLNcmzUX66qvmXxEjm00kuvk0Hv4eX3pS6J_gAgSHFlfAG-GtjMLVjHDe0SFEytRGLWvw9lLngklD6ZWicnTStf4zM3psFV1myIeA4/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+17+testing+with+an+id+in+the+browser.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm7EyR7meFXf9LTUxEp51rXm0LivX-CI6jSJBtGjgLNcmzUX66qvmXxEjm00kuvk0Hv4eX3pS6J_gAgSHFlfAG-GtjMLVjHDe0SFEytRGLWvw9lLngklD6ZWicnTStf4zM3psFV1myIeA4/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+17+testing+with+an+id+in+the+browser.png" class="screenshot-standard" /></a>
<br>
<br>
Now we have to connect the GET contacts/id action to our real data.
<h3>Updating the code of contactsDataHandler.js</h3>
open contactsDataHandler.js in Visual Studio code and add:
<br>
a refence to the npm module jsonpath that will serve us to retrieve a contact based on its id.
a function with the id in parameter to retrieve the contact.
<br>
<br>
here is the updated complete code:
<pre class="code-standard">
'use strict';
var contacts = require('./contacts.json');
var jp = require('jsonpath')
module.exports = {
get: function (id) {
return jp.query(contacts, '$..[?(@.id=='+id+')]');
},
all: function () {
return contacts;
}
};
</pre>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsjWD3BUbGPZw-n1D0LNdpj0UeuXtnkhPVXT2rGaXrWM0cxjkE-O5sfxVh_Hf9ZaJq97S3OZGF077P99zCQEasOpQ_Zv6egfBOoWg7r3Hn69-ht_0tzub4068EAujFPGZdKwU3d5nV-8J/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+18+contactsDataHandler.js+updated.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsjWD3BUbGPZw-n1D0LNdpj0UeuXtnkhPVXT2rGaXrWM0cxjkE-O5sfxVh_Hf9ZaJq97S3OZGF077P99zCQEasOpQ_Zv6egfBOoWg7r3Hn69-ht_0tzub4068EAujFPGZdKwU3d5nV-8J/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+18+contactsDataHandler.js+updated.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Updating the code of contacts\{id}.js</h3>
open contacts\{id}.js file in Visual Studio code and replace the code in it by this one:
<pre class="code-standard">
'use strict';
var repository = require('../../data/contactsDataHandler');
module.exports = {
get: function contacts_get(req, res) {
res.json(repository.get(req.params['id']))
}
};
</pre>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0QuuQfD3aYVZEeGyF0jSMA7CdCr-6gPTqWJ7DbVb_ZQ1YMLE7oSgPVcw9FsP655Rw6sFY3ErRZfHbaorbFA9BYx9cgXFLgf3OocBPytS0KE5buL11yoLDdpNYS8PIAmt6yGIfoycoGRfc/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+19+contaroller+%257Bid%257D.js+updated.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0QuuQfD3aYVZEeGyF0jSMA7CdCr-6gPTqWJ7DbVb_ZQ1YMLE7oSgPVcw9FsP655Rw6sFY3ErRZfHbaorbFA9BYx9cgXFLgf3OocBPytS0KE5buL11yoLDdpNYS8PIAmt6yGIfoycoGRfc/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+19+contaroller+%257Bid%257D.js+updated.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>testing the action GET/contacts/id</h3>
We can test the developed code now but before to do that we have to install the npm jsonpath module we declared and used in the contacts dataHandler.
<br>
So type:
npm install jsonpath in your command prompt.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFYdr4MVgcHoI-6UT556-u8PNYPtKjuknwd1zsZV5e42Sqaf1Irb_4bTkw4IUz7qoy3ivoGEzGgsnOm9vXO205ZBjAtwXeIOnufFe_zdKRhAogesMv4UGboKSeVgNxg0nAAN3R9bYaXMQd/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+installing+npm+jsonpath.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFYdr4MVgcHoI-6UT556-u8PNYPtKjuknwd1zsZV5e42Sqaf1Irb_4bTkw4IUz7qoy3ivoGEzGgsnOm9vXO205ZBjAtwXeIOnufFe_zdKRhAogesMv4UGboKSeVgNxg0nAAN3R9bYaXMQd/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+installing+npm+jsonpath.png" class="screenshot-standard" /></a>
<br>
<br>
Then we can test and get the expected result
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu1zQkCIEfaLl16HO7_mvzhNkhf3P5MFde34y_moLeFyMqHfsV1qydp3qdpcdrO-2VgxaUtv-brKmq3jvjm054cYjF_RgGp6wG61jP9h5TI9sRNPXLnOdpbrCtx1fJ0aDCZR9af5twYIdL/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+testing+with+an+id+in+the+browser.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu1zQkCIEfaLl16HO7_mvzhNkhf3P5MFde34y_moLeFyMqHfsV1qydp3qdpcdrO-2VgxaUtv-brKmq3jvjm054cYjF_RgGp6wG61jP9h5TI9sRNPXLnOdpbrCtx1fJ0aDCZR9af5twYIdL/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+testing+with+an+id+in+the+browser.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Deleting mockgen.js</h3>
we can now delete the mockgen.js file because we don't need it anymore since all is pointing on our real data stored in our contacts.json file.
<br>
At this step the project should look like this on your machine:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPrP8TM7InxNFox42gPk04VIevMBOvsb-qzfiZJFuMFsVcG3pI5Ekvl16yLbzNuUlO1ZgKteF2lbaRG6fPSsqYC1fjVHYMz_6pZ-YfAR1foBfy2LpvZF6_3A3fJs3ZTP8So1GUsj_uVjqG/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+project+view+before+deployment.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPrP8TM7InxNFox42gPk04VIevMBOvsb-qzfiZJFuMFsVcG3pI5Ekvl16yLbzNuUlO1ZgKteF2lbaRG6fPSsqYC1fjVHYMz_6pZ-YfAR1foBfy2LpvZF6_3A3fJs3ZTP8So1GUsj_uVjqG/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+20+project+view+before+deployment.png" class="screenshot-standard" /></a>
<br>
<br>
Well done! the last thing to do is to deploy all this in Azure and the job is done.
<br>
<br>
<h2 id="deployment">Deploying the Swaggerize REST API into an Azure App Service</h2>
<h3>Last update before deploying, server.js file</h3>
We are going to use for this deployment the "Try Azure App Service" feature that offers to take benefit of the Azure portal very quickly for one hour. You just have to have one of this social account (Microsoft, Google, Facebook, Github).
<br>
<br>
But before opening an one hour trial for the Azure App Services we have to prepare our project for the deployment.
<br>
The App Service we are targetting for deploying is an empty Web App.
<br>
Unfortunately, our server.js file generated automatically by Swaggerize-express isn't totally compliant with this Azure empty Web App we are targetting for deploying.
We thus have to update our server.js file.
<br>
So open it in your editor and replace its code with the following:
<pre class="code-standard">
'use strict';
var port = process.env.PORT || 8000; // first change
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var swaggerize = require('swaggerize-express');
var swaggerUi = require('swaggerize-ui'); // second change
var path = require('path');
var app = express();
var server = http.createServer(app);
app.use(bodyParser.json());
app.use(swaggerize({
api: path.resolve('./config/api.json'), // third change
handlers: path.resolve('./handlers'),
docspath: '/swagger' // fourth change
}));
// change four
app.use('/docs', swaggerUi({
docs: '/swagger'
}));
server.listen(port, function () { // fifth and final change
});
</pre>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEAk3r_9yngavv4f8WfWJkIAikXLBeU3H90kBDSbiicp4gfMN2wz67Sq1wggSDq9Uo19Tj74P_ML3OPDuMgWC6oWruz2Ah7ByAfsLzQNgsneCNCcpXGp_fYc2rYpV7fT5c4JYYWeJo8HrV/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+22+server.js+file+updated.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEAk3r_9yngavv4f8WfWJkIAikXLBeU3H90kBDSbiicp4gfMN2wz67Sq1wggSDq9Uo19Tj74P_ML3OPDuMgWC6oWruz2Ah7ByAfsLzQNgsneCNCcpXGp_fYc2rYpV7fT5c4JYYWeJo8HrV/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+22+server.js+file+updated.png" class="screenshot-standard" /></a>
<br>
<br>
If we want to test locally a last time before deploying we have first to install swaggerize-ui npm module. It is also important for Azure because this local installation will be tracked in our local project and tell Azure that the module is needed within the Azure environment.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnAK-is58JbT40lnTTAbqlDobBMmZt6uU1hSlKxibgbUCJBu-T8GaIwoZKcWdXpkTXpwM7j5bjZE2q-Ju6IqNFT_K4gzm4F9wpu4t4YAvYAtc_1ueveXzd4m4BtYh68g3U9i-YrBgC6DX/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+23+installing+npm+swaggerize-ui.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnAK-is58JbT40lnTTAbqlDobBMmZt6uU1hSlKxibgbUCJBu-T8GaIwoZKcWdXpkTXpwM7j5bjZE2q-Ju6IqNFT_K4gzm4F9wpu4t4YAvYAtc_1ueveXzd4m4BtYh68g3U9i-YrBgC6DX/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+23+installing+npm+swaggerize-ui.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Creating the "Try Azure App Service" Azure App Service to host the project</h3>
So let's deploy our Node.js REST API into this type of Azure App Service, totally free and without any commitment
For enjoying this Azure feature, reach the welcome page of <a href="https://azure.microsoft.com/en-us/try/app-service/" target="blank">"Try Azure App Service"</a>
<br>
<br>
<a href="https://azure.microsoft.com/en-us/try/app-service/" target="blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtmlU4HYN9up9wRv1EPKqnUXpK_cEtEYcOJGICsVNk4yFOrQs2aXmlcWseCYm29vT-9DNmZzfY3csS1Hu6mdX-LRV8eCxMh1mg9OR_kUB3VX_8CAEfURz3jz4WRzYvYnLG_pxdjv7734ZB/s1600/azure-app-service-node.js-api-swaggerize+-+10+-+Try+Azure+app+service+portal+.png" class="screenshot-standard"/></a>
<br>
<br>
You notice that there is only 2 types of Web App available. Previously, until mid 2018, we had API App and Serverles Apps (Logic App and Function). But there was dramatic changes in App Servics from mid 2018. You can consult <a href="https://mosshowto.blogspot.com/2017/10/azure-app-service.html">my other post if you want to know more on this topic.</a>
You are then invited to choose the type of App Service you want to try. There is not a lot of choice. As we don't use containers we have to select the Web App. You will see that you can totally use a Web App for hosting a Node.js REST API. From summer 2018, the only resource running an application (Web site, API, Mobile Backend) in Azure App Services, is the Web App .
Thus, select the Web App, then click Next.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjZBrZSREWXyzVx0NFQgEmTioHyZFXn6z00LfkfIVNn_qupYjTnHITq_SSLUVHLozg_DhxIG18zl-UVSUEfk_jD87-Puh-uKfIUYr1zcKVgVz5dpgojDyJEgMDoqG9HOtp2Vs1Ck6pA9L/s1600/try-azure-app-service+-+01+-+select+the+Web+App+template.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjZBrZSREWXyzVx0NFQgEmTioHyZFXn6z00LfkfIVNn_qupYjTnHITq_SSLUVHLozg_DhxIG18zl-UVSUEfk_jD87-Puh-uKfIUYr1zcKVgVz5dpgojDyJEgMDoqG9HOtp2Vs1Ck6pA9L/s1000/try-azure-app-service+-+01+-+select+the+Web+App+template.png" class="screenshot-standard" /></a>
<br>
<br>
Now is the time to chose the template.
Before 2018 we had a template Node.js + Express but is has been removed. The others were left.
Anyway, you will see that an Azure App Services "Empty Site" is "smart enough" to "understand" that we are going to deploy a Node.js RESTful API on it and make it work.
Thus chose the empty Web App and click on "Create".
As wrritten previously you can use one of the 4 social networks account to sign in : Microsoft (live), Google +, Facebook, Github. For the demonstration I will use my Live account.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6AasAnD_chPtshBgMkB1X2A8h5wlyXVmQis0EvWPWMb-Ax1QLwCWtJaMvWtOqifCW8daCGmQ1jsmW7BT2TMpeKkdvUZ2lwhmoWPxD0_Ra6W_RUh3J4KH-EuKn2jsQbmXCZsnxCGPpS9Ks/s1600/Try+Azure+App+Service+-+12+-+signing+with+a+social+account+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6AasAnD_chPtshBgMkB1X2A8h5wlyXVmQis0EvWPWMb-Ax1QLwCWtJaMvWtOqifCW8daCGmQ1jsmW7BT2TMpeKkdvUZ2lwhmoWPxD0_Ra6W_RUh3J4KH-EuKn2jsQbmXCZsnxCGPpS9Ks/s1600/Try+Azure+App+Service+-+12+-+signing+with+a+social+account+.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHJQMaBKQbTuC3O_63YAeteMSV6X3hHHUpqguEq1yYgx4TaAx_3LL_up4AKBl4meT-ZxcriMRspm6gZeWDMjY1JuLgK_j64GrhTC7PWUjc6pl7itndMPC24SGk4MQp7xpQGu5FK3b-S30S/s1600/Try+Azure+App+Service+-+120+-+signing+with+a+social+account+step2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHJQMaBKQbTuC3O_63YAeteMSV6X3hHHUpqguEq1yYgx4TaAx_3LL_up4AKBl4meT-ZxcriMRspm6gZeWDMjY1JuLgK_j64GrhTC7PWUjc6pl7itndMPC24SGk4MQp7xpQGu5FK3b-S30S/s1600/Try+Azure+App+Service+-+120+-+signing+with+a+social+account+step2.png" class="screenshot-standard"/></a>
<br>
<br>
Then, Azure is provisionning your App Service in a few seconds.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZBI5eGCZglbFf1CylepBBb8ZDEDvpxNfilW0-xHAg14yI4ZJDe217xqu0SqhuTVAVqUYG3h6jnO1XwRNJGbQhDWJK0CHa5ye2KGWdlOyJOxq4EhsgYwSR73ZrtjxH4qM_y4Cl5CTPqSNM/s1600/Try-Azure-App-Service+-+03+-+waiting+for+service+to+be+provisionned+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZBI5eGCZglbFf1CylepBBb8ZDEDvpxNfilW0-xHAg14yI4ZJDe217xqu0SqhuTVAVqUYG3h6jnO1XwRNJGbQhDWJK0CHa5ye2KGWdlOyJOxq4EhsgYwSR73ZrtjxH4qM_y4Cl5CTPqSNM/s1000/Try-Azure-App-Service+-+03+-+waiting+for+service+to+be+provisionned+.png" class="screenshot-standard" /></a>
<br>
<br>
And an ONE Hour countdown is starting lettting you play with the Azure App Service and the Azure Portal within this hour.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCrzmtzgOxz7GTJN3fw4ivdnnbeodQn3wKdm1HCG9YvdHJVgUohB21zukVNlWF8DY8eaLsYDcbU3jpuc2v7J_dQ2TLbD3e0QjO-dkaUcWwiu7QE0aYwKl9twEmWbc3MHRNndXeL7RKLbd/s1600/Try-Azure-App-Service+-+03+-+service+provisionned+-+count+down+started.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCrzmtzgOxz7GTJN3fw4ivdnnbeodQn3wKdm1HCG9YvdHJVgUohB21zukVNlWF8DY8eaLsYDcbU3jpuc2v7J_dQ2TLbD3e0QjO-dkaUcWwiu7QE0aYwKl9twEmWbc3MHRNndXeL7RKLbd/s1600/Try-Azure-App-Service+-+03+-+service+provisionned+-+count+down+started.png" class="screenshot-standard" /></a>
<br>
<br>
Before mid 2018, we were able to go to the Azure Portal from this UI and see the porperties of the Web App but it's over now. We were also able to change the API file code online using the App Service Editor (Visual Studio Code online), but it has been replaced by Kudu. But you can navigate throguh the Web App folders and modify them using Kudu. You can also deploy an API by uploading files to Kudu. I have <a href="https://mosshowto.blogspot.com/2017/10/try-azure-app-service.html#deployment">another post that shows how to do it.</a>
<br>
<br>
<h3>Creating a .gitignore file</h3>
We have to prepare the deployment with another step. We have to exclude the thousand files of the npm modules installed locally in our project to prevent them to be deployed in Azure. Azure has them anyway or can get them at the deployment time much more faster than to deploy them from our local machine.
<br>
<br>
The best way to create a .gitignore file is to create it within Visual Studion Code. Add a file named .gitignore at the root of your code repo:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMlYXytMVYI7BnfrF91t7mAAU63fld2pDkVudVjReiFTzqRBAMhwgAdwsmnjR2J8XFsFO6AlP2-FfcWLMx8QIeWClZE9IiZHbiy6Tcx75BIymUNDadfc6wATbhsB-sL_V6a1F3XftLZg3K/s1600/azure-app-service-node.js-api-swaggerize+-+24+-+create+.gitignore+file+in+VS+Code+%25282%2529.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMlYXytMVYI7BnfrF91t7mAAU63fld2pDkVudVjReiFTzqRBAMhwgAdwsmnjR2J8XFsFO6AlP2-FfcWLMx8QIeWClZE9IiZHbiy6Tcx75BIymUNDadfc6wATbhsB-sL_V6a1F3XftLZg3K/s1600/azure-app-service-node.js-api-swaggerize+-+24+-+create+.gitignore+file+in+VS+Code+%25282%2529.png" class="screenshot-medium" /></a>
<br>
<br>
then paste the following lines to avoid pushing the node modules and the readme file to the Azure Web App folders when deploying:
<pre class="code-standard">
/node_modules
*.md
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpSqHdVRDlKuit4gSY3PnCBrA2fUkl7mZyd2j44bVOyj1mgJ0lfyNihnpFnIzgC-L-XCX_tbiwz08o1mYHSV__KqnXT2b1CilY9dx_utXWWVrT4MRzTUFAOKB5cZtNgn1AUgoTPXxWmSzP/s1600/azure-app-service-node.js-api-swaggerize+-+25+-+.gitignore+file+created+in+VS+Code+%25282%2529.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpSqHdVRDlKuit4gSY3PnCBrA2fUkl7mZyd2j44bVOyj1mgJ0lfyNihnpFnIzgC-L-XCX_tbiwz08o1mYHSV__KqnXT2b1CilY9dx_utXWWVrT4MRzTUFAOKB5cZtNgn1AUgoTPXxWmSzP/s1000/azure-app-service-node.js-api-swaggerize+-+25+-+.gitignore+file+created+in+VS+Code+%25282%2529.png" class="screenshot-large" /></a>
<br>
<br>
<div style="padding-left:20px;">
<b>trick to use if you have not Visual Studio Code </b>and you want to create the .gitignore file (that has no name and only an extension):
Create a gitignore.txt file at the root of your project and paste (my screenshot is wrong I forgot the "s" to "moduleS"):<br>
node_modules/
<br>
in it
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvBwMuXiz28SDNiGSQ_I-s5rodt1xxlQ9wKCjlkdOX_R8xL9Xyup9ac34lvLnPocFKHdzc0svEdKx_dRiMYNEGhp21IKEaCbWNbzn-4-RxQZ1YEBfa4A8waqWDVqmz9hWYMcdMhNlrLThs/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+24+.gitignore+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvBwMuXiz28SDNiGSQ_I-s5rodt1xxlQ9wKCjlkdOX_R8xL9Xyup9ac34lvLnPocFKHdzc0svEdKx_dRiMYNEGhp21IKEaCbWNbzn-4-RxQZ1YEBfa4A8waqWDVqmz9hWYMcdMhNlrLThs/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+24+.gitignore+file.png" data-original-width="1300" class="screenshot-standard" /></a>
<br>
<br>
Then if you are on Windows OS, press the right-shift key of your keyboard and right-click a blank space inside your folder (not a file) and select "open a powershell window from here" in the contextual menu.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK_0D6ycfV2flqV7DXoW_PoOeSIHk2qOk99P_txj5pIY1xR2mNnLKR0ujIPpZLV21IxtIyw3byYdJ0dZVFEvbey2oYv2McDG_5MwNNtPKcdLgcOOZ_cU_y59eg5f8ISePf9Ddn0enRPig7/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+25+.gitignore+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK_0D6ycfV2flqV7DXoW_PoOeSIHk2qOk99P_txj5pIY1xR2mNnLKR0ujIPpZLV21IxtIyw3byYdJ0dZVFEvbey2oYv2McDG_5MwNNtPKcdLgcOOZ_cU_y59eg5f8ISePf9Ddn0enRPig7/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+25+.gitignore+file.png" class="screenshot-standard" /></a>
<br>
<br>
In the powershell prompt type:
<br>
ren gitignore.txt .gitignore.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQpUEcVNrSjAVzI15hOrsAe4Sp3nnOYcIOJZDykRHsGKzNlmySyNWYjPgemyJXyRzUaLiJhyLphmjxnW7XVAyK2ap_-L94bu3k7CxmTGL35Aji4WidNpUFVP-9iQevvPq7RdYPm4oD8ONc/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+26+.gitignore+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQpUEcVNrSjAVzI15hOrsAe4Sp3nnOYcIOJZDykRHsGKzNlmySyNWYjPgemyJXyRzUaLiJhyLphmjxnW7XVAyK2ap_-L94bu3k7CxmTGL35Aji4WidNpUFVP-9iQevvPq7RdYPm4oD8ONc/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+26+.gitignore+file.png" class="screenshot-standard" /></a>
</div>
<br>
<br>
<h3>Deploying the Swaggerize-express API into Azure</h3>
Open the Integrated Terminal of visual studio code.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy01h3RY-D5XXiX-rfRFifVUjM-klPdVS4uNah_3R7ArDGJA5CIDU0wnyEMEkOEvIveZOJDRh0mHxR6WEc1SaprPG2EHO8zOn2PGEXqpYzfnA9fowHgGmTfEHoKPaPb0eMS8KTrWVAuod5/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+27+opening+visual+studio+code+integrated+terminal.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy01h3RY-D5XXiX-rfRFifVUjM-klPdVS4uNah_3R7ArDGJA5CIDU0wnyEMEkOEvIveZOJDRh0mHxR6WEc1SaprPG2EHO8zOn2PGEXqpYzfnA9fowHgGmTfEHoKPaPb0eMS8KTrWVAuod5/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+27+opening+visual+studio+code+integrated+terminal.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmHQoyqhiQIvtG4xxfELyeL9bWABe6uPqKLR1uMORvuZkNVxYW_ndiQIMpXHPwIk5-X-58AmQ_YXtVOGA0PNMTtJYmhAWW2OZujUM1u_J4cvYPaqT9bicp98HSzc_3TfiRLVjvC5_vGTd2/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+28+visual+studio+code+integrated+terminal+open.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmHQoyqhiQIvtG4xxfELyeL9bWABe6uPqKLR1uMORvuZkNVxYW_ndiQIMpXHPwIk5-X-58AmQ_YXtVOGA0PNMTtJYmhAWW2OZujUM1u_J4cvYPaqT9bicp98HSzc_3TfiRLVjvC5_vGTd2/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+28+visual+studio+code+integrated+terminal+open.png" class="screenshot-standard" /></a>
<br>
<br>
type
<br>
git init .
<br>to initialize the git feature for the deployment
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQh2fOB2YPldYEL652ZPzxT2Kj9IBWaPtHh1V04U4nB1-ZR3-2uwAdP9yHunn33XkOLKJOmj-JPkTHjr1A3UizCJWhteIto78MpOXgDxaZnSBIQw1pFz_5DXyPDLYk2bnH4EJffxgObHE/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+29+visual+studio+code+integrated+terminal+git+init+..png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQh2fOB2YPldYEL652ZPzxT2Kj9IBWaPtHh1V04U4nB1-ZR3-2uwAdP9yHunn33XkOLKJOmj-JPkTHjr1A3UizCJWhteIto78MpOXgDxaZnSBIQw1pFz_5DXyPDLYk2bnH4EJffxgObHE/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+29+visual+studio+code+integrated+terminal+git+init+..png" class="screenshot-standard" /></a>
<br>
<br>
Check with<br>
git status<br>
that the files under node_modules would be excluded (the next screenshots are from a command prompt, good way to avoid problems of credentials cache in VS code)
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJye1E21XQCRyVe86YnFfN9D-MrRpbKpVwoy48eaWiV_r6XeD25mL3j4YoR5C5ZJVgucqjcYLxFxqL1c8MPzKzzYVIFDjT3fG6t6V2Rr_kvUWNno0uH90UFu8HZxNXYOWkwhu0IEuZN_3/s1600/azure-app-service-node.js-api-swaggerize+-+27+-+deploying+node.js+api+to+Azure+Web+App+-+git+init.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJye1E21XQCRyVe86YnFfN9D-MrRpbKpVwoy48eaWiV_r6XeD25mL3j4YoR5C5ZJVgucqjcYLxFxqL1c8MPzKzzYVIFDjT3fG6t6V2Rr_kvUWNno0uH90UFu8HZxNXYOWkwhu0IEuZN_3/s1600/azure-app-service-node.js-api-swaggerize+-+27+-+deploying+node.js+api+to+Azure+Web+App+-+git+init.png" class="screenshot-standard" /></a>
<br>
<br>
then type<br>
git add . <br>
to add all the files references to the future deployment
<br>All the files of node_modules should not be taken into account thanks to the .gitignore file.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA9p0X6Bq7aMmo6NvyOR1jtHI_3LiCqEVR65L4NZf077IjgoA5x14SbwkSYkoXxWXU6cGmXRQuMX9jzu-Y7ZL2pbBXPs12EuFpGAdpGOajhVQh-nCGNwfSlwGF_jF6VRYnHw4EpQQhYBBC/s1600/azure-app-service-node.js-api-swaggerize+-+28-+deploying+node.js+api+to+Azure+Web+App+-+git+add.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA9p0X6Bq7aMmo6NvyOR1jtHI_3LiCqEVR65L4NZf077IjgoA5x14SbwkSYkoXxWXU6cGmXRQuMX9jzu-Y7ZL2pbBXPs12EuFpGAdpGOajhVQh-nCGNwfSlwGF_jF6VRYnHw4EpQQhYBBC/s1600/azure-app-service-node.js-api-swaggerize+-+28-+deploying+node.js+api+to+Azure+Web+App+-+git+add.png" class="screenshot-standard" /></a>
<br>
<br>
Now commit all the changes to prepared them to be pushed in Azure. All is new so type: <br>
git commit -m "initial commit"
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglkx5vRf2hyj-mddUxbg8MFENNocohYjaY-DjDJuBXtIypLrF2Q0rG4zk1tr0-CbwyQy_zSLfySWjsCn3oHc0osb9v9mdFz64gT1B-F4rFMcrkHlRKZ1mgg43qJmW3cLc4gKeMQwM0tw_f/s1600/azure-app-service-node.js-api-swaggerize+-+29+-+deploying+node.js+api+to+Azure+Web+App+-+git+commit.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglkx5vRf2hyj-mddUxbg8MFENNocohYjaY-DjDJuBXtIypLrF2Q0rG4zk1tr0-CbwyQy_zSLfySWjsCn3oHc0osb9v9mdFz64gT1B-F4rFMcrkHlRKZ1mgg43qJmW3cLc4gKeMQwM0tw_f/s1600/azure-app-service-node.js-api-swaggerize+-+29+-+deploying+node.js+api+to+Azure+Web+App+-+git+commit.png" class="screenshot-standard"/></a>
<br>
<br>
When the commit is finished, it's time to deploy, so we are going to add the reference to our Azure App Service
<br>
Go back to the "Try Azure App Service" welcome page were the countdown is running and pick the git url by clicking on the "clone or push with git" button. Copy the url in your clipboard.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicIDZxhUNZEWXyc9JT7mqCeBTgwrnWd6T2Y5yhmwmTvt_rrQWTo8ifluzox3tjLv1sOYRy4Xe5EVie7efyd0UpvcuzAPbfyr8IImwzmY0m4Aozh7ZNzZMh_1TNni-nn23-sIKO-l9DOUCZ/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+32+Try+Azure+App+Service+Git+url.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicIDZxhUNZEWXyc9JT7mqCeBTgwrnWd6T2Y5yhmwmTvt_rrQWTo8ifluzox3tjLv1sOYRy4Xe5EVie7efyd0UpvcuzAPbfyr8IImwzmY0m4Aozh7ZNzZMh_1TNni-nn23-sIKO-l9DOUCZ/s1600/build+a+swaggerize-express+rest+api+and+deploy+it+in+a+Microsoft+Azure+App+Service+-+32+Try+Azure+App+Service+Git+url.png" class="screenshot-standard" /></a>
<br>
<br>
Then type <br>
git remote add AzureWebApp<br>
and right click the Integrated Terminal to paste the Azure App Service git url
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFFtu5XtdiPuDpIQWTaikSkKNXJXd-ps_CeX-pYmRLfvZ0uTNzqdP4jCUco-Tm1oLNwNkIiUro3vWc0FvwPSkPuXZXK3GuGo6DSfHa2HToiLPPALg1fmakwbO3zccxu8C8cHuNdue8O_1b/s1600/azure-app-service-node.js-api-swaggerize+-+30+-+deploying+node.js+api+to+Azure+Web+App+-+git+remote+add.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFFtu5XtdiPuDpIQWTaikSkKNXJXd-ps_CeX-pYmRLfvZ0uTNzqdP4jCUco-Tm1oLNwNkIiUro3vWc0FvwPSkPuXZXK3GuGo6DSfHa2HToiLPPALg1fmakwbO3zccxu8C8cHuNdue8O_1b/s1600/azure-app-service-node.js-api-swaggerize+-+30+-+deploying+node.js+api+to+Azure+Web+App+-+git+remote+add.png" class="screenshot-standard" /></a>
<br>
<br>
then for deploying, type:
<br>
git push AzureWebApp
<br>
The git command will correct you and you will be able to execute the right command.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPUjGxMipxpIXckcj90ey1-g8yocLAb6WCsT3w2KKyl6h31kW6WOjmKMXTotkaxKWhx_xue3GYii1T0a59TgPEGLj3vjpeEb6qzU3Ie4Ze9KLCXz-TcselrC6wr3r9zYqVyMLE34biIVSI/s1600/azure-app-service-node.js-api-swaggerize+-+31+-+deploying+node.js+api+to+Azure+Web+App+-+git+push.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPUjGxMipxpIXckcj90ey1-g8yocLAb6WCsT3w2KKyl6h31kW6WOjmKMXTotkaxKWhx_xue3GYii1T0a59TgPEGLj3vjpeEb6qzU3Ie4Ze9KLCXz-TcselrC6wr3r9zYqVyMLE34biIVSI/s1600/azure-app-service-node.js-api-swaggerize+-+31+-+deploying+node.js+api+to+Azure+Web+App+-+git+push.png" data-original-width="1105" class="screenshot-standard"/></a>
<br>
<br>
Deployment is starting. Kudu, the Azure App Service build engine, warns you that it is updating the master branch of the Web App. The Azure Web App is a real git repo.
<br>
Then Kudu understands that a Node.js application is intended to be deployed
<br>
Then the files begin to be copied to the Web App folder: wwwroot.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7Q6t_eedAMt7lKR3SMLGJwW6WABwZiwBdxoux53GgP7LtHYjDbF3hrHcTQFSsBRjDalPpecudwqjXz-TrwOF8hPt5nYr5Dc_tQrKrEFjeoLenX1EKxZKSAP2FUiaKVH0nGuVHmm1vrirZ/s1600/azure-app-service-node.js-api-swaggerize+-+32+-+deploying+node.js+api+to+Azure+Web+App+-+file+copying.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7Q6t_eedAMt7lKR3SMLGJwW6WABwZiwBdxoux53GgP7LtHYjDbF3hrHcTQFSsBRjDalPpecudwqjXz-TrwOF8hPt5nYr5Dc_tQrKrEFjeoLenX1EKxZKSAP2FUiaKVH0nGuVHmm1vrirZ/s1600/azure-app-service-node.js-api-swaggerize+-+32+-+deploying+node.js+api+to+Azure+Web+App+-+file+copying.png" class="screenshot-standard"/></a>
<br>
<br>
then Kudu:
<ul>
<li>creates the web.config file, (we are in a windows environment, no such file in linux)</li>
<li> decides to take the server.js file as iisnode. Sometimes, it seems that if the node.js version is fixed, Kudu creates a iisnode.yml file to manage the good execution of the node.js application within the Azure Web App. In this deployment, no iisnode.yml file was created. Just a web.config (no iisnode.yml file neither in a Linux Web App).
<li>checks a reference for the node version, doesn't find in the package.json, decides the best version to use for node and npm, checks the packages, warns you to the packages to update. </li>
</ul>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7tinUAOGR_IVrGzcjC-Qhq_Ma_Lnw_9AM1Bf1ZaMsNLPjTz8ejhRNP5s7z2B9BeGPVt7E79xGx5bE_RuLZ31j4npGhcTaoRtNnFS2uyq87GKhRAqDSYChJ4WUtYU2RLebm8l3UBsU8RH/s1600/azure-app-service-node.js-api-swaggerize+-+33+-+deploying+node.js+api+to+Azure+Web+App+-+creating+web.config+-+checking+node.js+version%252C+warning+on+node+packages.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7tinUAOGR_IVrGzcjC-Qhq_Ma_Lnw_9AM1Bf1ZaMsNLPjTz8ejhRNP5s7z2B9BeGPVt7E79xGx5bE_RuLZ31j4npGhcTaoRtNnFS2uyq87GKhRAqDSYChJ4WUtYU2RLebm8l3UBsU8RH/s1600/azure-app-service-node.js-api-swaggerize+-+33+-+deploying+node.js+api+to+Azure+Web+App+-+creating+web.config+-+checking+node.js+version%252C+warning+on+node+packages.png" class="screenshot-standard"/></a>
<br>
<br>
Then Kudu performs an NPM install to get all the Node.js packages required for the API:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7fUhNv55hTyDjWNca65J1q7UKNJqEM5vP_jUdOghZCBgoMxrX2ef37Ppv4zRchyEkbSA7g9fjqXR7IK2CHP4He16LCicnT0CbruZ5l08gal9G4N0R7MhOnVNATAM6m53ak0pgS3LzZaq0/s1600/azure-app-service-node.js-api-swaggerize+-+34+-+deploying+node.js+api+to+Azure+Web+App+-+performing+npm+install.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7fUhNv55hTyDjWNca65J1q7UKNJqEM5vP_jUdOghZCBgoMxrX2ef37Ppv4zRchyEkbSA7g9fjqXR7IK2CHP4He16LCicnT0CbruZ5l08gal9G4N0R7MhOnVNATAM6m53ak0pgS3LzZaq0/s1600/azure-app-service-node.js-api-swaggerize+-+34+-+deploying+node.js+api+to+Azure+Web+App+-+performing+npm+install.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWzrADhdTcxlKoyUUxY1MPRnEyXOMfYZKyIjQVLX0fsYgPcEZb1mYzzFPKScKmfpEuKGAPNlB2a4wVjK3TsFEBN1SOLVWLNLoDKD6RvRDAKlrSgsXOGPW97z2UrAkaFoy2kQ_i7H0UbmuO/s1600/azure-app-service-node.js-api-swaggerize+-+36+-+deploying+node.js+api+to+Azure+Web+App+-+deployment+successful.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWzrADhdTcxlKoyUUxY1MPRnEyXOMfYZKyIjQVLX0fsYgPcEZb1mYzzFPKScKmfpEuKGAPNlB2a4wVjK3TsFEBN1SOLVWLNLoDKD6RvRDAKlrSgsXOGPW97z2UrAkaFoy2kQ_i7H0UbmuO/s1600/azure-app-service-node.js-api-swaggerize+-+36+-+deploying+node.js+api+to+Azure+Web+App+-+deployment+successful.png" class="screenshot-standard" /></a>
<br>
<br>
The deployment is successful.
<br>
We can check the deployment by visiting Kudu:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnV5zQDOfo9RkBlWPOe_IQg6O_mxP7TX9mw6Nurz0Bq2a1hSyMNztk53vJg0lgVFhiMlVh9y7P6_1nZTBC0PnO9dQ7RBudF1EsMrnpmSAUCjF-FpsXoXdpGAfRGI3k5zKTQPXlpUnmOGU1/s1600/azure-app-service-node.js-api-swaggerize+-+37+-+deploying+node.js+api+to+Azure+Web+App+-+chacking+deployment.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnV5zQDOfo9RkBlWPOe_IQg6O_mxP7TX9mw6Nurz0Bq2a1hSyMNztk53vJg0lgVFhiMlVh9y7P6_1nZTBC0PnO9dQ7RBudF1EsMrnpmSAUCjF-FpsXoXdpGAfRGI3k5zKTQPXlpUnmOGU1/s1000/azure-app-service-node.js-api-swaggerize+-+37+-+deploying+node.js+api+to+Azure+Web+App+-+chacking+deployment.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY7iVtMgQOKhJg1p6mxDQgWEAf7D5AHEUZI0maLmyLRr9jalI5d3IUjYWFtP9vuH34vvguWd9GuvMhTc5ddvtKU0hcYRC_DG8C8N6TZgvyYJj0MSa1z8tTz3Xaz3SQK-QjQAzjAK3k3IJn/s1600/azure-app-service-node.js-api-swaggerize+-+38+-+deploying+node.js+api+to+Azure+Web+App+-+checking+deployment+-+Kudu+open.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY7iVtMgQOKhJg1p6mxDQgWEAf7D5AHEUZI0maLmyLRr9jalI5d3IUjYWFtP9vuH34vvguWd9GuvMhTc5ddvtKU0hcYRC_DG8C8N6TZgvyYJj0MSa1z8tTz3Xaz3SQK-QjQAzjAK3k3IJn/s1000/azure-app-service-node.js-api-swaggerize+-+38+-+deploying+node.js+api+to+Azure+Web+App+-+checking+deployment+-+Kudu+open.png" class="screenshot-standard" /></a>
<br>
<br>
You can see the files of the API and the web.config file created by Kudu during the deployment.
<br>
and you can even edit this file and other online.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicf88L1b5Mn2juAImMj7LfLKswjSxtqBViqqh91PhkXc2cYfM-HeB8uVL4PkoLvaGMm2T39a4k8ElSz1BEvNOm2-u0B9KKOcRrV5uSg3GqTwWCeDw6mNhT4Pp_ibwexaXrO-USBdCG3fa/s1600/azure-app-service-node.js-api-swaggerize+-+39+-+deploying+node.js+api+to+Azure+Web+App+-+checking+deployment+-+Kudu+open+-+editing+web.config+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicf88L1b5Mn2juAImMj7LfLKswjSxtqBViqqh91PhkXc2cYfM-HeB8uVL4PkoLvaGMm2T39a4k8ElSz1BEvNOm2-u0B9KKOcRrV5uSg3GqTwWCeDw6mNhT4Pp_ibwexaXrO-USBdCG3fa/s1600/azure-app-service-node.js-api-swaggerize+-+39+-+deploying+node.js+api+to+Azure+Web+App+-+checking+deployment+-+Kudu+open+-+editing+web.config+file.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>Testing the deployement</h2>
For testing the API after the deployment, just click on its url on the Try App Service welcome page:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhilGlI5uvMFmI9cN2BxhAbirdwUQNN-oBy0ux5mYtbP84T21o3-eJiQoeNvA1HbCHO5blf4_28_FG5tYLeVy27UqyUMl584JGxG3rHMn4_6EVXYztPbk7ZwAa-BCwRPIKGnkTB62FH_bpU/s1600/azure-app-service-node.js-api-swaggerize+-+39+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhilGlI5uvMFmI9cN2BxhAbirdwUQNN-oBy0ux5mYtbP84T21o3-eJiQoeNvA1HbCHO5blf4_28_FG5tYLeVy27UqyUMl584JGxG3rHMn4_6EVXYztPbk7ZwAa-BCwRPIKGnkTB62FH_bpU/s1000/azure-app-service-node.js-api-swaggerize+-+39+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment.png" class="screenshot-standard" /></a>
<br>
<br>
You will get an error on the root site because we didn't implement the GET / site route, but if you complete the root site url with /contacts you will have the pleasure to notice that everyhting is ok.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF1IFClC1sCS0BMrBehjnc9045utO5XrE9iy6K_AK-rY4KB6PvcHSIsqBlGdGUf9LP83T8pfGRPE35GfYVx62cfbY1V01warJBeIm_3Mdk9ridGLn347UG367pDb5MgS_PXG10QYd1mn_4/s1600/azure-app-service-node.js-api-swaggerize+-+40+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF1IFClC1sCS0BMrBehjnc9045utO5XrE9iy6K_AK-rY4KB6PvcHSIsqBlGdGUf9LP83T8pfGRPE35GfYVx62cfbY1V01warJBeIm_3Mdk9ridGLn347UG367pDb5MgS_PXG10QYd1mn_4/s1600/azure-app-service-node.js-api-swaggerize+-+40+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>Testing the Azure REST API with swagger</h2>
Last we can use swagger to test our API online.
<br>
The correct syntax for the Url to display our API in Swagger UI is
<br>
<br>
yourAzureAppUrl/docs
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfP_QYXwvQoB7AEBLuZv6WBLj_G2NcudJv6i-vD5SGwsi-jVo4gvMPKIgHPFL5xTS7B1Ch-yTN-NP2zPNfXnyDTZYBOm6K_puqfmCipRDBDLbzFpMAt6BrGYbSokxuHzmYuLrcm6ujureI/s1600/azure-app-service-node.js-api-swaggerize+-+41+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment+swagger.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfP_QYXwvQoB7AEBLuZv6WBLj_G2NcudJv6i-vD5SGwsi-jVo4gvMPKIgHPFL5xTS7B1Ch-yTN-NP2zPNfXnyDTZYBOm6K_puqfmCipRDBDLbzFpMAt6BrGYbSokxuHzmYuLrcm6ujureI/s1600/azure-app-service-node.js-api-swaggerize+-+41+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment+swagger.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPQ0aJI0w8F_ZYC7XhIxOZImo6vHtCyd5EP6hAV1cy1UoZWZ39UG361PxYrMos5PAD1fqbHkh1_hWdu3NEPXJYutTAkUdgyDT-Mb3H6UF0OkT4g2oJtdTCwT5U3ZhHcOLrpsQaHa-Giz-X/s1600/azure-app-service-node.js-api-swaggerize+-+42+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment+swagger.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPQ0aJI0w8F_ZYC7XhIxOZImo6vHtCyd5EP6hAV1cy1UoZWZ39UG361PxYrMos5PAD1fqbHkh1_hWdu3NEPXJYutTAkUdgyDT-Mb3H6UF0OkT4g2oJtdTCwT5U3ZhHcOLrpsQaHa-Giz-X/s1600/azure-app-service-node.js-api-swaggerize+-+42+-+deploying+node.js+api+to+Azure+Web+App+-+testing+deployment+swagger.png" class="screenshot-standard" /></a>
<br>
<br>
Enjoy folks!
<br>
<br>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-42327788759980478872017-10-21T14:19:00.001+02:002019-09-11T10:15:56.119+02:00Try Azure App Service: deploy manually a node.js API (Kudu Upload)<span style="color:red">Updated 2019 sept. 6th</span>
<h2>Introduction</h2>
<div class="h2-paragraph">
This post shows how to <span class="highlight">quicly deploy a Node.js API to an Azure App Service empty Web App using only manual operations.</span>
<br>
It is an update of the old post written 2 years ago. "Try App Service" is a portal offered by Microsoft Azure that allows you to test the App Services Web App quickly <span class="highlight">without having to use the credit card information.</span>
<br>
<br>
Normally, when you want to give a try to Azure Portal you can open a free account for one month but you have to provide Microsoft with a credit card information.
With the "Try Azure App Service" feature you can play with Web App during one hour by just signing with a social account (Live (Microsoft), Google +, Facebook, Github).
<br>You can also test Web App for Containers but you must have a Microsoft account (need to already have an Azure Porrtal so need to have given your credit cards informations previously)
<h2>Creating a Web App for an one hour trial</h2>
So let's deploy a Node.js REST API into this type of Azure App Service, totally free and without any commitment
For enjoying this Azure feature, reach the welcome page of <a href="https://azure.microsoft.com/en-in/try/app-service/" target="blank">"Try Azure App Service"</a>
<br>
<br>
<a href="https://azure.microsoft.com/en-in/try/app-service/" target="blank" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi51Vd-D5UOw3SX-sulmTOfcJ6UxJlOPnOjCXOiCWGtr9vMeQDsm2HEsq7Q-7WpMUZ1zIZ3O2ky7iNp3NL7dIyBE3rf8JTmJq6TAhtEoXEozF7wlzl7VJGpWWBK8faWZeYCaFzdDhgQUGjB/s1600/try-azure-app-service+-+00+-+Try+Azure+app+service+portal+.png" class="screenshot-standard" /></a>
<br>
<br>
You notice that there is only 2 types of Web App available. Previously, until mid 2018, we had API App and Serverles Apps (Logic App and Function). But there was dramatic changes in App Servics from mid 2018. You can consult <a href="https://mosshowto.blogspot.com/2017/10/azure-app-service.html">my other post if you want to know more on this topic.</a>
<br>
You are then invited to choose the type of App Service you want to try. There is not a lot of choice. As we don't use containers we have to select the Web App. You will see that you can totally use a Web App for hosting a Node.js REST API. From summer 2018, the only resource running an application (Web site, API, Mobile Backend) in Azure App Services, is the Web App . <br>
Thus, select the Web App, then click Next.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjZBrZSREWXyzVx0NFQgEmTioHyZFXn6z00LfkfIVNn_qupYjTnHITq_SSLUVHLozg_DhxIG18zl-UVSUEfk_jD87-Puh-uKfIUYr1zcKVgVz5dpgojDyJEgMDoqG9HOtp2Vs1Ck6pA9L/s1600/try-azure-app-service+-+01+-+select+the+Web+App+template.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjZBrZSREWXyzVx0NFQgEmTioHyZFXn6z00LfkfIVNn_qupYjTnHITq_SSLUVHLozg_DhxIG18zl-UVSUEfk_jD87-Puh-uKfIUYr1zcKVgVz5dpgojDyJEgMDoqG9HOtp2Vs1Ck6pA9L/s1600/try-azure-app-service+-+01+-+select+the+Web+App+template.png" data-original-width="1600" class="screenshot-standard" /></a>
<br>
<br>
Now is the time to chose the template.
<br>Before 2018 we had a template Node.js + Express but is has been removed. The others were left.
<br>
Anyway, you will see that an Azure App Services "Empty Site" is "smart enough" to "understand" that we are going to deploy a Node.js RESTful API on it and make it work. <br>Thus chose the empty Web App and click on "Create".
<br>As wrritten previously you can use one of the 4 social networks account to sign in : Microsoft (live), Google +, Facebook, Github. For the demonstration I will use my Live account.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgredsW2WcdDhTQ08E4cyW-YayCB_1Q0EQ9yQj9zBDrN9fzENs3cbsYETTOCKNzANYMrNhGmx4rwBlXoGepzDsgbhQXQcK-_BK8W_BOOcNdeXvUBhLY5Vh8BEQZCPkmGLM4uviCgcNtzG2q/s1600/Try+Azure+App+Service+-+12+-+signing+with+a+social+account++%25281%2529.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgredsW2WcdDhTQ08E4cyW-YayCB_1Q0EQ9yQj9zBDrN9fzENs3cbsYETTOCKNzANYMrNhGmx4rwBlXoGepzDsgbhQXQcK-_BK8W_BOOcNdeXvUBhLY5Vh8BEQZCPkmGLM4uviCgcNtzG2q/s1600/Try+Azure+App+Service+-+12+-+signing+with+a+social+account++%25281%2529.png" data-original-width="1600" class="screenshot-standard"/></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHJQMaBKQbTuC3O_63YAeteMSV6X3hHHUpqguEq1yYgx4TaAx_3LL_up4AKBl4meT-ZxcriMRspm6gZeWDMjY1JuLgK_j64GrhTC7PWUjc6pl7itndMPC24SGk4MQp7xpQGu5FK3b-S30S/s1600/Try+Azure+App+Service+-+120+-+signing+with+a+social+account+step2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHJQMaBKQbTuC3O_63YAeteMSV6X3hHHUpqguEq1yYgx4TaAx_3LL_up4AKBl4meT-ZxcriMRspm6gZeWDMjY1JuLgK_j64GrhTC7PWUjc6pl7itndMPC24SGk4MQp7xpQGu5FK3b-S30S/s1600/Try+Azure+App+Service+-+120+-+signing+with+a+social+account+step2.png" class="screenshot-standard"/></a>
<br>
<br>
Then, Azure is provisionning your App Service in a few seconds.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZBI5eGCZglbFf1CylepBBb8ZDEDvpxNfilW0-xHAg14yI4ZJDe217xqu0SqhuTVAVqUYG3h6jnO1XwRNJGbQhDWJK0CHa5ye2KGWdlOyJOxq4EhsgYwSR73ZrtjxH4qM_y4Cl5CTPqSNM/s1600/Try-Azure-App-Service+-+03+-+waiting+for+service+to+be+provisionned+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZBI5eGCZglbFf1CylepBBb8ZDEDvpxNfilW0-xHAg14yI4ZJDe217xqu0SqhuTVAVqUYG3h6jnO1XwRNJGbQhDWJK0CHa5ye2KGWdlOyJOxq4EhsgYwSR73ZrtjxH4qM_y4Cl5CTPqSNM/s1600/Try-Azure-App-Service+-+03+-+waiting+for+service+to+be+provisionned+.png" class="screenshot-standard" /></a>
<br>
<br>
And an ONE Hour countdown is starting lettting you play with the Azure App Service and the Azure Portal within this hour.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCrzmtzgOxz7GTJN3fw4ivdnnbeodQn3wKdm1HCG9YvdHJVgUohB21zukVNlWF8DY8eaLsYDcbU3jpuc2v7J_dQ2TLbD3e0QjO-dkaUcWwiu7QE0aYwKl9twEmWbc3MHRNndXeL7RKLbd/s1600/Try-Azure-App-Service+-+03+-+service+provisionned+-+count+down+started.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCrzmtzgOxz7GTJN3fw4ivdnnbeodQn3wKdm1HCG9YvdHJVgUohB21zukVNlWF8DY8eaLsYDcbU3jpuc2v7J_dQ2TLbD3e0QjO-dkaUcWwiu7QE0aYwKl9twEmWbc3MHRNndXeL7RKLbd/s1600/Try-Azure-App-Service+-+03+-+service+provisionned+-+count+down+started.png" class="screenshot-standard" /></a>
<br>
<br>
Before mid 2018, we were able to go to the Azure Portal from this UI and see the porperties of the Web App but it's over now. We were also able to change the API file code online using the App Service Editor (Visual Studio Code online), but it has been replaced by Kudu. However, this is not a bad thing, because we are going to use Kudu to deploy manually our Node.js RESTful API!
<!--deploying to Azure App Service -->
<h2 id="deployment">Deploying manually a Node.js API into the Azure App Service</h2>
There is a lot of way now to deploy some code to an Azure Web App. You can:
<ul>
<li>Use automated process (Azure Devops)</li>
<li>Do semi-manual operation using an FTP transfer tool: FTP tranfer</li>
<li>Use Git commands: for example, deploy code from a GitHub repo to the Web App using git . Actually it is a push with Git to the Web App. The Web App can behave as a real git repo. <a href="https://mosshowto.blogspot.com/2017/10/nodejs-swaggerize-api-into-azure-app.html#deployment">See this other post to do that.</a></li>
<li>Do it manually:
<ul>
<li>Using the Web App Build Service (Kudu) to pull code from a GitHub repo. <a href="https://mosshowto.blogspot.com/2017/10/quick-tutorial-nodejs-app-service-azure.html#deployment">See this other post to do that</a></li>
<li>Directly upload files to the Web App file sytem using Kudu. This is that we are going to do now. </li>
</ul>
</ul>
<h3>Downloading the code to deploy</h3>
We are going to deploy a REST API based on Node.js in our Azure Web App Service within a few minutes and test it.
<br>
Download the <a href="https://github.com/MarcCharmois/app-service-api-node-contact-list">Contact List REST API sample</a> on my Github repositery.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3KTC1lfxY5LU0IA6XLDexm9y6DOzWczoiADaj0MNdSIuDj9pkLbDyV_biMU8RsHF40bwJp-Wfoz_fNI16XUJcU0Pmh2_38hyphenhyphenev1GaTuQlToiMzPcbn2AJEU5B0u5mhVtaD39Ccdxz95HG/s1600/try-azure-app-service+-+26+-+before+package+download+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3KTC1lfxY5LU0IA6XLDexm9y6DOzWczoiADaj0MNdSIuDj9pkLbDyV_biMU8RsHF40bwJp-Wfoz_fNI16XUJcU0Pmh2_38hyphenhyphenev1GaTuQlToiMzPcbn2AJEU5B0u5mhVtaD39Ccdxz95HG/s1600/try-azure-app-service+-+26+-+before+package+download+.png" class="screenshot-standard" /></a>
<br>
<br>
Place the downloaded zip file in your local dev repositery and for Windows, right-click it and locate Extract All in the contextual menu.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Ax8iKR8VNt6hELEwjFxfjE3UY1k7EgQawwcG1orRr7Zy2-4T1mESHd70-lUTOUpTlLhKhdAeUUO0VmAdFZo9lPhP26ZX7h5Z0ZnTy3bQo10ZeD4jakIvoGPg5nOi9wapMnfwha3Ry9aZ/s1600/Try+Azure+App+Service+-+20+-+Extracting+the+Contact+List+REST+API+Sample+zip+file.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Ax8iKR8VNt6hELEwjFxfjE3UY1k7EgQawwcG1orRr7Zy2-4T1mESHd70-lUTOUpTlLhKhdAeUUO0VmAdFZo9lPhP26ZX7h5Z0ZnTy3bQo10ZeD4jakIvoGPg5nOi9wapMnfwha3Ry9aZ/s1600/Try+Azure+App+Service+-+20+-+Extracting+the+Contact+List+REST+API+Sample+zip+file.png" class="screenshot-standard" /></a>
<br>
<br>
On next screen delete the last segment of the path for not having this folder created twice as a main folder and a sub folder with exactly the same name.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9nDeXzA_WORXNNBBK-fEDz1PLT1Z9BQh-DG5VoagS0RL9ngfoLDPP7V9H6HpfB0NSQQ0xTIaS1sIBHxZjr_UehZN4lUkVl0srk04mKrMH3pzaab1dL6cr2camnOVRpbu3FKTX1a86on2O/s1600/Try+Azure+App+Service+-+21+-+Extracting+the+Contact+List+REST+API+Sample+zip+file+step+2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9nDeXzA_WORXNNBBK-fEDz1PLT1Z9BQh-DG5VoagS0RL9ngfoLDPP7V9H6HpfB0NSQQ0xTIaS1sIBHxZjr_UehZN4lUkVl0srk04mKrMH3pzaab1dL6cr2camnOVRpbu3FKTX1a86on2O/s1600/Try+Azure+App+Service+-+21+-+Extracting+the+Contact+List+REST+API+Sample+zip+file+step+2.png" class="screenshot-standard" /></a>
<br>
<br>
You should obtain this view (for Windows) after having extracted the GitHub sample zip file.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiah5-p7Ck0lx10OWTl0xVhTa7RTv1mqRrbOQNl3N_8yphWQXEEicyzLJPvD9BWmd83ddecdQcD8NYzyDXOIB2nmxGFpMaQANHzYzR53uJR4RJETFgCXbWcltGe8JlSZwWt7u3fUmWHOXRJ/s1600/try-azure-app-service+-+30+-+package+extracted+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiah5-p7Ck0lx10OWTl0xVhTa7RTv1mqRrbOQNl3N_8yphWQXEEicyzLJPvD9BWmd83ddecdQcD8NYzyDXOIB2nmxGFpMaQANHzYzR53uJR4RJETFgCXbWcltGe8JlSZwWt7u3fUmWHOXRJ/s1600/try-azure-app-service+-+30+-+package+extracted+.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Deploying the code manually (drag and drop in the browser)</h3>
<br>
You can then go back to the Microsoft Azure "Try Azure App Service" this time to use the button "Edit your code online" to open Kudu in this version of "try Azure App Service" (in the last version this link was opening App Service Editor).
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrZKBVk3qW56SMftZLZKl2mEZ3eHxqNrPgcGCFIOPFmzhyWA_6vwIaWuhdphL9FjAjPaBLTblWH_ce-TmCSmAxTmlsM6Ei1jFIUKy_Sam4HqVDzjNTleBrLYJlwOz_Xj9QZrr-OkueRHUe/s1600/try-azure-app-service+-+20+-+before+opening+Kudu.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrZKBVk3qW56SMftZLZKl2mEZ3eHxqNrPgcGCFIOPFmzhyWA_6vwIaWuhdphL9FjAjPaBLTblWH_ce-TmCSmAxTmlsM6Ei1jFIUKy_Sam4HqVDzjNTleBrLYJlwOz_Xj9QZrr-OkueRHUe/s1600/try-azure-app-service+-+20+-+before+opening+Kudu.png" class="screenshot-standard" /></a>
<br>
<br>
You land on the Kudu welcome page
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjceNhwhp8yT9QzBaY22Y7oyG0Qmt-j1YCXwLYEq24t0z8V1xPSpYvHtTsDQa25JdL-yA3FYrp1kpHQ3SoORCjN4AFtasAxV63D4AQG56LxytsJJLE5fGXyY9zwfzYYlp8f3VDrZHfxangJ/s1600/try-azure-app-service+-+20+-+Kudu+welcome+page.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjceNhwhp8yT9QzBaY22Y7oyG0Qmt-j1YCXwLYEq24t0z8V1xPSpYvHtTsDQa25JdL-yA3FYrp1kpHQ3SoORCjN4AFtasAxV63D4AQG56LxytsJJLE5fGXyY9zwfzYYlp8f3VDrZHfxangJ/s1600/try-azure-app-service+-+20+-+Kudu+welcome+page.png" class="screenshot-standard" /></a>
<br>
<br>
Next locate the CMD menu item and open it
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxaKZlgQSet_efrz9MeEUZxx6-TunHfM1VWcwcsk4m9zZ0lMXwC6kDTwZWC3TKghWVyxTCMxZcJywGa2P38mltukeEop3AkxzNtgrQSuT2ad0U4-Yg537OluQ-O8cbdMlmcGQcB0fNjMD0/s1600/try-azure-app-service+-+21+-+Kudu+CMDl+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxaKZlgQSet_efrz9MeEUZxx6-TunHfM1VWcwcsk4m9zZ0lMXwC6kDTwZWC3TKghWVyxTCMxZcJywGa2P38mltukeEop3AkxzNtgrQSuT2ad0U4-Yg537OluQ-O8cbdMlmcGQcB0fNjMD0/s1600/try-azure-app-service+-+21+-+Kudu+CMDl+.png" class="screenshot-standard"/></a>
<br>
<br>
then navigate to wwwroot by clicking on Site.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4GexTTyliozaOzvyKzP6k46dajZr9uTLcL7HAj7W7vRo-jVrKWI9pO4FAic4yorazFed8LVdbaZrm5-7NKqRk2ybA30ecaLYqn9uzt8InzTXl4uDX6oHGGuxpU1kociyCIjt7mCzmf6D2/s1600/try-azure-app-service+-+23+-Kudu+CMD+open+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4GexTTyliozaOzvyKzP6k46dajZr9uTLcL7HAj7W7vRo-jVrKWI9pO4FAic4yorazFed8LVdbaZrm5-7NKqRk2ybA30ecaLYqn9uzt8InzTXl4uDX6oHGGuxpU1kociyCIjt7mCzmf6D2/s1600/try-azure-app-service+-+23+-Kudu+CMD+open+.png" class="screenshot-standard" /></a>
<br>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwDQl1iPA1Lo2pROTvBDbUf7iwSGL71ueBMrivFX9LFFd1SpsTY36UzylImRs6cm7t1KSyxvxVAxqZj9v9iCXltZnXIxLyR4xQVpJncfCf38SIHUMo-2woWtUXrxxRFDg1bznlnh4JBpct/s1600/try-azure-app-service+-+024+-open+site+naviagte+to+wwwroot+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwDQl1iPA1Lo2pROTvBDbUf7iwSGL71ueBMrivFX9LFFd1SpsTY36UzylImRs6cm7t1KSyxvxVAxqZj9v9iCXltZnXIxLyR4xQVpJncfCf38SIHUMo-2woWtUXrxxRFDg1bznlnh4JBpct/s1600/try-azure-app-service+-+024+-open+site+naviagte+to+wwwroot+.png" class="screenshot-standard"/></a>
<br>
<br>
Click on the folder wwwroot to open it. Drag and drop all the folders and files excepted iisnode.yml and web.config (and of course, test, gitignore and readme) in the wwwroot folder in your browser.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs7ba2l8LqWKNn11gT9NTYFCbsppWXtpni2TjbVM7-ArRvUewVZnhagpcONf7jmfrPSNw-rsD01LSr27AAA9Jg-gYsZwVOSzPwMFksFn_fix0GxotrTu2xM0wWJhFnbyPcg0CaWfjziMpq/s1600/try-azure-app-service+-+32+-+first+upload+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs7ba2l8LqWKNn11gT9NTYFCbsppWXtpni2TjbVM7-ArRvUewVZnhagpcONf7jmfrPSNw-rsD01LSr27AAA9Jg-gYsZwVOSzPwMFksFn_fix0GxotrTu2xM0wWJhFnbyPcg0CaWfjziMpq/s1600/try-azure-app-service+-+32+-+first+upload+.png" class="screenshot-standard" /></a>
<br>
<br>
The first upload takes time because of the node_modules folder but in a few minutes you should get this:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxG1mxamg3jIHQD998rwz480HByClLzk_CWogHQoU1OnYzJ3ytkvjUDtNTYAB_raVf6w1HfnFV-6Iw6-558LadUP4_EbhwVcjGh_lfGM9w_1Ow3K2SOpQGIb3G210Sz6RYEq_EXF0qoL6W/s1600/try-azure-app-service+-+34+-+first+upload+done+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxG1mxamg3jIHQD998rwz480HByClLzk_CWogHQoU1OnYzJ3ytkvjUDtNTYAB_raVf6w1HfnFV-6Iw6-558LadUP4_EbhwVcjGh_lfGM9w_1Ow3K2SOpQGIb3G210Sz6RYEq_EXF0qoL6W/s1600/try-azure-app-service+-+34+-+first+upload+done+.png" class="screenshot-standard" /></a>
<br>
<br>
then drag and drop iisnode.yml, and finally the web.config file.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJoGv3eJRsrGMlcDGtVrrEHdXUbUO0G5WURplAJiltJs_FHSbCzz6TbrmUjdd-URccLnfPxPcuExWEJiz5nBbJl8tONbIzG0vceQHfizrnBVb-yrLFrZVtRU3SyK3ygW7fAuAV-ve_MPVQ/s1600/try-azure-app-service+-+36+-+second+uplaod+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJoGv3eJRsrGMlcDGtVrrEHdXUbUO0G5WURplAJiltJs_FHSbCzz6TbrmUjdd-URccLnfPxPcuExWEJiz5nBbJl8tONbIzG0vceQHfizrnBVb-yrLFrZVtRU3SyK3ygW7fAuAV-ve_MPVQ/s1600/try-azure-app-service+-+36+-+second+uplaod+.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZZ8YVjEzH4p5x2j7jUAkL_Xt-9FEz-WJqZdJ3trlmwLa6pEaPwuYfyXDeR5wFJWkhqxWdZ50mUNgQf7ZsHohYV4NSM2fY353MXMngSXtn8JK5WgkCNd4CYYhCr9ybAsX6OHEYZsYcz7Z5/s1600/try-azure-app-service+-+38+-+last+upload+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZZ8YVjEzH4p5x2j7jUAkL_Xt-9FEz-WJqZdJ3trlmwLa6pEaPwuYfyXDeR5wFJWkhqxWdZ50mUNgQf7ZsHohYV4NSM2fY353MXMngSXtn8JK5WgkCNd4CYYhCr9ybAsX6OHEYZsYcz7Z5/s1000/try-azure-app-service+-+38+-+last+upload+.png" class="screenshot-standard" /></a>
<br>
<br>
You can now come back to your Try App Service welcome page to click on the API url.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjay2At7410wRUuQntDXAGvU7iAgIrtUJx-QLYg7YaKsZD57fTEOOYTHnSdweTqnib5FLJ4raUgJv7l5QkhyZy9cNotpc7VnT5kz0uXa0lMFX7RcaeQ7eMwureVjAEIi5det_DWcqZ59PTp/s1600/Try-Azure-App-Service+-+35+-+Web+App+Url.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjay2At7410wRUuQntDXAGvU7iAgIrtUJx-QLYg7YaKsZD57fTEOOYTHnSdweTqnib5FLJ4raUgJv7l5QkhyZy9cNotpc7VnT5kz0uXa0lMFX7RcaeQ7eMwureVjAEIi5det_DWcqZ59PTp/s1000/Try-Azure-App-Service+-+35+-+Web+App+Url.png" class="screenshot-standard" /></a>
<br>
<br>
You should obtain this result. I customized the out of the box welcome page of the Try App Service Web App:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGvl17urOfLhZpsiJgb5ftVZ-Ydgy5bLDw9CdsJTP9apiGSgc1XyTF4TbOXvYvS8enhrBZ2YPwoWSEzAhoDwHsi0GxVe1YTGwgDCYYiAQrOr5GVzLLy_kLVuM3Vj-WROBuiE59k5g3ZRz/s1600/Try-Azure-App-Service+-+40+-+Web+App+Contacts+API+-+Welcome+page.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGvl17urOfLhZpsiJgb5ftVZ-Ydgy5bLDw9CdsJTP9apiGSgc1XyTF4TbOXvYvS8enhrBZ2YPwoWSEzAhoDwHsi0GxVe1YTGwgDCYYiAQrOr5GVzLLy_kLVuM3Vj-WROBuiE59k5g3ZRz/s1600/Try-Azure-App-Service+-+40+-+Web+App+Contacts+API+-+Welcome+page.png" class="screenshot-standard" /></a>
<br>
<br>
If you click on the "See contacts" button, you will see the Azure Web App serving the JSON of your Restful your API.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdvVu5UbDkZbVNBA3U_-7mMYmeIDWsn04EqCVwH3tXIEZl6gaoRBBDX1HvEZwlGuajWTMwetlAtcGVd12m1GPABoB65FGbAwqcERNvQ4UoFrnuEeVysDws6vTB-1Kkmeh515VDF3_ELFYn/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+Contacts+displaying.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdvVu5UbDkZbVNBA3U_-7mMYmeIDWsn04EqCVwH3tXIEZl6gaoRBBDX1HvEZwlGuajWTMwetlAtcGVd12m1GPABoB65FGbAwqcERNvQ4UoFrnuEeVysDws6vTB-1Kkmeh515VDF3_ELFYn/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+Contacts+displaying.png" class="screenshot-standard" /></a>
<br>
<br>
If you clcik on the "Use Swagger" button, you will be able to test your API with swagger UI:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPJiJXwFRne68S_Wwzkn1BLGq_NdwYyFKc1-XW0vHS8CXicSnK7AKSjsCqNHDdr4SJ3yVUMFyHPhuZvRYFZDnkJU8smvLs6AzGS2YLs4EBYpL_WC31shdqxnCLub3T8prwObR30fdkiorf/s1600/try-azure-app-service+-+40+-+swgger1+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPJiJXwFRne68S_Wwzkn1BLGq_NdwYyFKc1-XW0vHS8CXicSnK7AKSjsCqNHDdr4SJ3yVUMFyHPhuZvRYFZDnkJU8smvLs6AzGS2YLs4EBYpL_WC31shdqxnCLub3T8prwObR30fdkiorf/s1600/try-azure-app-service+-+40+-+swgger1+.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5Q-JCsKqTIXv9_0uhBv7rhGzN_h9_TvDAaI3i250bhqUc-LIGPYrQyDYTvz5QXvh6u6K7WcE3siNQmG0LsLkMDbi6coIb4-0f7XfPpjstmlRZPm6AG4VbS3t_8aQKisDpFaR0XjGml2tC/s1600/try-azure-app-service+-+42+-+swagger+2+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5Q-JCsKqTIXv9_0uhBv7rhGzN_h9_TvDAaI3i250bhqUc-LIGPYrQyDYTvz5QXvh6u6K7WcE3siNQmG0LsLkMDbi6coIb4-0f7XfPpjstmlRZPm6AG4VbS3t_8aQKisDpFaR0XjGml2tC/s1600/try-azure-app-service+-+42+-+swagger+2+.png" class="screenshot-standard" /></a>
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbtsYNyT8BsNt48TsaQ0-dp1BIgiNr1nro9JjjRbWUus3rTYvqgnrcFE5QBmYge1lYtkGXI8qkT9Zl1Bpz1wW1hXi-stA8CficDS7GaFgRYSFYATvSsfjRzqhq93aQLw9MK8MyTw3u4qBL/s1600/try-azure-app-service+-+45+-+swagger+3+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbtsYNyT8BsNt48TsaQ0-dp1BIgiNr1nro9JjjRbWUus3rTYvqgnrcFE5QBmYge1lYtkGXI8qkT9Zl1Bpz1wW1hXi-stA8CficDS7GaFgRYSFYATvSsfjRzqhq93aQLw9MK8MyTw3u4qBL/s1600/try-azure-app-service+-+45+-+swagger+3+.png" class="screenshot-standard" /></a><br>
<br>
<!--editing Azure App Service online-->
<h2>Editing online a Node.js API deployed into the Azure App Service</h2>
One of the good point of Node.js compared to compiled language like .Net C# is that you can all edit online once deployed.
<br>
Assume we want to add a new contact to our API. We just have to write it on the proper file and it is possible with Kudu, so open the file contacts.json located in the lib folder
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK9qOyF4HVVXBKav7flfpI_v0E-SyK25QdfzS-Jgv-jtcrSC7Qq26XPgkJIRxteXEHu5HTXtQD8eWddz2hiodRO8AU58aKZnCz0QYXrnm014nNLkud3c-eQvZhjN6DMyYp92K9Q_r27OV_/s1600/try-azure-app-service+-+47+-+opening+contacts.json.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK9qOyF4HVVXBKav7flfpI_v0E-SyK25QdfzS-Jgv-jtcrSC7Qq26XPgkJIRxteXEHu5HTXtQD8eWddz2hiodRO8AU58aKZnCz0QYXrnm014nNLkud3c-eQvZhjN6DMyYp92K9Q_r27OV_/s1600/try-azure-app-service+-+47+-+opening+contacts.json.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks1MZaPmQh7ieFNRMoE5qz7TO_gqvkpGnuY1r9vRC1gmK7IB7tt_FBKEANEPYLMb80xC1hGXF15nXD6t9Rwf-5p5SaW0hMhNc-8nHp01PKjl26IaNJtjc1tRK8a2Q575kNIKZ2HFG-shX/s1600/try-azure-app-service+-+48+-+contacts.json+open+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks1MZaPmQh7ieFNRMoE5qz7TO_gqvkpGnuY1r9vRC1gmK7IB7tt_FBKEANEPYLMb80xC1hGXF15nXD6t9Rwf-5p5SaW0hMhNc-8nHp01PKjl26IaNJtjc1tRK8a2Q575kNIKZ2HFG-shX/s1600/try-azure-app-service+-+48+-+contacts.json+open+.png" class="screenshot-standard" /></a>
<br>
<br>
Add a new contact and don't forget to save the file.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikNqJA1lAAC8_-OO3SbunKuKSnGSzLLKblgt32tUdews9Ex-AazztsV6XH4sL8G2ivFSYGeExWvjJGhrpbgphWwJYqj81yqln-GXaNW9cxwU6eJ8IMCnXoC8XhYmODdPEjsmCRXrHivTpS/s1600/try-azure-app-service+-+49+-+adding+a+contact+to+contacts.json.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikNqJA1lAAC8_-OO3SbunKuKSnGSzLLKblgt32tUdews9Ex-AazztsV6XH4sL8G2ivFSYGeExWvjJGhrpbgphWwJYqj81yqln-GXaNW9cxwU6eJ8IMCnXoC8XhYmODdPEjsmCRXrHivTpS/s1600/try-azure-app-service+-+49+-+adding+a+contact+to+contacts.json.png" class="screenshot-standard" /></a>
<br>
<br>
Now, if you test in Swagger you see that your change wasn't taken into account.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih5NFPk5Rv20L5e2RsLTBbGJU6-51Sw0LyMU2NFa329qviwoWHqJUlCVPzSgxuTZKje1HSWYFdCArwoJtsHoqdILEs6JBpF8MS36yAHIxkGKYgo_5Uxp0ii4KVYpRzYyueOTnE2Epyc-jk/s1600/try-azure-app-service+-+50+-+change+cannot+be+seen.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih5NFPk5Rv20L5e2RsLTBbGJU6-51Sw0LyMU2NFa329qviwoWHqJUlCVPzSgxuTZKje1HSWYFdCArwoJtsHoqdILEs6JBpF8MS36yAHIxkGKYgo_5Uxp0ii4KVYpRzYyueOTnE2Epyc-jk/s1600/try-azure-app-service+-+50+-+change+cannot+be+seen.png" class="screenshot-standard" /></a>
<br>
<br>
Why ? Because your data are in cache and you have to restart the web App for them to be taken into account. One good way to this on Windows server is to do an IISReset. Let's try to do this.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2cjCBzx-DAEVRZVaVtrBe6bOFKuYJXWZkFKWN6jg2mM7rgjhzH7JzrBOcqZyxpxNDCsjpsoGLg7dVY967duPIsnt_ICbFPVGqVmcXM620pyylpTW5u9yIgumuqtIRj56BbJzGri87pgWh/s1600/try-azure-app-service+-+52+-+impossible+to+make+an+IISRESET.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2cjCBzx-DAEVRZVaVtrBe6bOFKuYJXWZkFKWN6jg2mM7rgjhzH7JzrBOcqZyxpxNDCsjpsoGLg7dVY967duPIsnt_ICbFPVGqVmcXM620pyylpTW5u9yIgumuqtIRj56BbJzGri87pgWh/s1600/try-azure-app-service+-+52+-+impossible+to+make+an+IISRESET.png" class="screenshot-standard" /></a>
<br>
<br>
Of course, not a surprise, you cannot restart a Web App that way on the platform "Try Azure App Service". But I will show you a trick to do it anyway:
<br>
Locate the web.config file at the root of your site an open it.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOij1ihyAu5pZT8ca3PGZCmhYw98NqDKuq9wWlOzhkUDbmmEtREQxQeGZltxMMqtCrFNG4NVQv9o6x4_farVKNfOqRmBaXx9nJEgOceSI-kc83PluUPgBeDYvaV8j4wUqO-AfetRdrEku4/s1600/try-azure-app-service+-+56+-+web.config+open.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOij1ihyAu5pZT8ca3PGZCmhYw98NqDKuq9wWlOzhkUDbmmEtREQxQeGZltxMMqtCrFNG4NVQv9o6x4_farVKNfOqRmBaXx9nJEgOceSI-kc83PluUPgBeDYvaV8j4wUqO-AfetRdrEku4/s1600/try-azure-app-service+-+56+-+web.config+open.png" class="screenshot-standard" /></a>
<br>
<br>
Change something not really relevant for the file, like removing an empty line.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijHjpaLR34phQ9cWLIztwkFRukvE04t-QIq8ZjFmhMRqDmdp4KqEWAJcgf_GhypQ-_1fC1mSzfm1cPB4DZF_GHukDje_ji_McdLhJ5rMXnxdBc2smLYd4vsqY4ESQ7Ta74Ri98FulPqrnx/s1600/try-azure-app-service+-+53+-+web.config+change+made.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijHjpaLR34phQ9cWLIztwkFRukvE04t-QIq8ZjFmhMRqDmdp4KqEWAJcgf_GhypQ-_1fC1mSzfm1cPB4DZF_GHukDje_ji_McdLhJ5rMXnxdBc2smLYd4vsqY4ESQ7Ta74Ri98FulPqrnx/s1600/try-azure-app-service+-+53+-+web.config+change+made.png" class="screenshot-standard"/></a>
<br>
<br>
Don't forget to save your change, then, test again by refreshing your Swagger UI page. You notice that the page refresh is a little bit longer than usual. It is normal, a change in the web.config file makes restart the Web App and when refreshing, it is a little bit longer, because IIS must reload the dll and the cache to run your API. You can then see your changes appear!
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEtOkw7-Oaw3rLc_D7qX7lSsRzn5cT3dWa7OdjhvfN_PyTKKhzGXzFIu4hL3DTU2rvg3RncXFzJG2R1MtfdngBwuf73LeSo_UNNvGZLUxYlHvlWAuRvzSN7DCqoOn-ykoqDH4kFarOlPk/s1600/try-azure-app-service+-+58+-+change+appears.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEtOkw7-Oaw3rLc_D7qX7lSsRzn5cT3dWa7OdjhvfN_PyTKKhzGXzFIu4hL3DTU2rvg3RncXFzJG2R1MtfdngBwuf73LeSo_UNNvGZLUxYlHvlWAuRvzSN7DCqoOn-ykoqDH4kFarOlPk/s1600/try-azure-app-service+-+58+-+change+appears.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>More information</h2>
<h3>1. Postman</h3>
You can also test your API in Postman.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnZ24fO3jjWeoaZrNrCfrRAgvfPSrr4zlR_mPOD6Qj6NUVjqJo7ydRXU9wrg8dLa_a3EeySgotzjIhsZPl2bdoCDqCQEdu-6lsoBzh1vxvtDfs-I57jEbH1jCZAAfhNWJpivZtUuQkAeC/s1600/Try+Azure+App+Service+-+41+-+editing+code+online+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnZ24fO3jjWeoaZrNrCfrRAgvfPSrr4zlR_mPOD6Qj6NUVjqJo7ydRXU9wrg8dLa_a3EeySgotzjIhsZPl2bdoCDqCQEdu-6lsoBzh1vxvtDfs-I57jEbH1jCZAAfhNWJpivZtUuQkAeC/s1600/Try+Azure+App+Service+-+41+-+editing+code+online+.png" class="screenshot-standard" /></a>
<br>
<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT7b0IpmHwlArFN8_GWXji8yZDvIMIw6qP6hJQPyUwAuos_-Li3kgzitUvtyuiKyj6-_U-HvmVhFiNuWtAUmIOqWtQoOK9ZSRaoUVop-proO4vAEXuB2-tZMyBPBiJMDNVGyBWy_MLxr5b/s1600/Try+Azure+App+Service+-+42+-+testing+the+changes+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT7b0IpmHwlArFN8_GWXji8yZDvIMIw6qP6hJQPyUwAuos_-Li3kgzitUvtyuiKyj6-_U-HvmVhFiNuWtAUmIOqWtQoOK9ZSRaoUVop-proO4vAEXuB2-tZMyBPBiJMDNVGyBWy_MLxr5b/s1600/Try+Azure+App+Service+-+42+-+testing+the+changes+.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>2. Mount a complete API with Swaggerize Express</h3>
If you want to know how to mount from scratch the API we have deployed in this post, <a href="https://mosshowto.blogspot.com/2017/10/nodejs-swaggerize-api-into-azure-app.html">I wrote a detailled post showing how to do it.</a>
<br>
<br>
Enjoy folks!
<br>
<br>
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-92114367626521002632017-10-10T20:30:00.002+02:002019-09-11T10:14:43.716+02:00Deploy manually a Node.js RESTful API from Github to an Azure Web App (Kudu fetch)
<span style="color:red">Updated 2019 sept. 2nd</span>
<h2>
Introduction</h2>
<div class="screenshot-large">
This post is a rework of an old Microsoft documentation <a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-rest-api">Build a Node.js RESTful API and deploy it to an API app in Azure</a> linked to this git hub sample <a href="https://github.com/Azure-Samples/app-service-api-node-contact-list">Azure-Samples/app-service-api-node-contact-list</a>. The documentation has been removed by Microsoft and the link points now to a tutorial showing how to deploy a RESTFull API based on .Net Core and using swagger and CORS. The link to the Microsoft github sample is still available, but we are not going to use this code, I had simplified it and posted the new code in a personal and public repo. We will use <a href="https://github.com/MarcCharmois/app-service-api-node-contact-list">this repo.</a>
<br>In this post, I focused on the detailed and complete steps with a lot of screen shots, <span style="background-color:yellow">so that the reader (even a newbie) can obtain a Node.js api running in Azure within a few minutes and with only manual operations!</span>
This quickstart shows how to :
<ul>
<li>create an Azure App Service to host your API</li>
<li>import locally a REST API, written with Node.js Express, using a Swagger definition</li>
<li>deploy it on Azure.</li>
</ul>
<h2>
Configuring your environment</h2>
<ul>
<li>
Create your <a href="https://azure.microsoft.com/en-us/free/?WT.mc_id=A261C142F">Azure free account</a>. Microsoft will ask for a credit card information for that...
<br><span style="background-color:yellow">If you don't have an Azure Free account and don't want to use a credit card</span>, I have posted an article to test Node.js deployment into an Azure App Service using the super cool "Try Azure App Service" Feature. <a href="http://mosshowto.blogspot.fr/2017/10/try-azure-app-service.html">It's here</a>...
<br>This feature doesn't offer all the possibilities of an Azure Free Account, but it could be a good start for discovering Azure Web Apps and Node.js deployment in Azure Web Apps.
<br>If you already have an Azure account or want a more professionnal environment for testing, just continue this post, if not <a href="http://mosshowto.blogspot.fr/2017/10/try-azure-app-service.html">switch to the other one.</a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgArwqG9ZBlAtXcItdw_tK8FTLpXft80LlQPF49aZRBjUEskMH3VjzOcmBonO2TkkbHPOLfJZQYvvAih3b3znMxLo4yAN2veZ07xj9dzYDeWTtfPxoxDXM1P_askgmuDvONEu3R_B8rCH5k/s1600/try-azure-app-service+-+00+-+Try+Azure+app+service+portal+.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgArwqG9ZBlAtXcItdw_tK8FTLpXft80LlQPF49aZRBjUEskMH3VjzOcmBonO2TkkbHPOLfJZQYvvAih3b3znMxLo4yAN2veZ07xj9dzYDeWTtfPxoxDXM1P_askgmuDvONEu3R_B8rCH5k/s1600/try-azure-app-service+-+00+-+Try+Azure+app+service+portal+.png" class="screenshot-standard" /></a>
<br>
<br>
</li>
</ul>
<br>
<h2>
Creating an Azure App Service to host the REST API</h2>
We are going to host our Node.js REST API into an Azure App Service, because this is the service to use in Azure to host APIs and Web Applications.
<br>
So, let's connect to <a href="https://portal.azure.com">Azure portal</a>
<br>
<h3>A little bit of history</h3>
From 2015, all the repositories for Web App, Mobile App backend, Web API have been gathered in an Azure offering called App Service in order all enjoy the same capabilities (behavior, insights, features,etc.). That means also they were quite the same and you were able to use a Web API App Service for a mobile backend and vice versa or a Web App App Service for hosting a Web API.
<br>
<br>
Since 2018 Mobile App (back-end API) seems to have been deprecated while the creation is still available in the portal.<br>
It seems, looking at the 2019 <a href="https://azure.microsoft.com/en-in/services/app-service/">Microsoft documentation for App Service</a> than we have now rather the choice between a Web App and an API app. However, in the portal, for App Service creation and <a href="https://docs.microsoft.com/en-us/azure/app-service/overview">this other Microsoft doc</a>, it seems to have actually no more disctintion, everything has become a Web App. Logic App and Azure Functions seem to have been removed from the App Service offer (while they are still mentioned in the Microsoft App Service documentation as serverless Apps, but not very visible...).
So let's create an App Service that will be a Web App since we have now, no more other choice left, using the left menu item in Azure Portal. For sumarizing, in 2019 App Service = Web App and hots everything: Web Applications (Web Sites), API and mobile back-end. Furthermore, New Web App is independant of the environement (Windows, Linux) and the techno, (.Net, PHP, Python, Node.js, etc.), and can host container (Docker).
<br>
<br>
You can retrieve the old classification (Web App, API App, Mobile App) using the "+" symbol and typing in the search area, but it is not the good way to create an App Service anymore, so we won't use the 2 following screenshots. I show them just as a curiosity.
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4vE7KqNjBjTR4Dp7fe8y7d-1M-zmc-OQclwvyLZjYWjFCHbKt5BCCEeUs2ebpPadz7koVGnwsK4Fy3VjCWnQVH8U7X9lGbFg-U7BjZz8_B1L3bLgfMrpSWxIscEaiewz-yF27PsmpEtU2/s1600/quick-tutorial-nodejs-app-service-azure+-+02+-+old+app+services+classification+-+Web+App+Api+App.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4vE7KqNjBjTR4Dp7fe8y7d-1M-zmc-OQclwvyLZjYWjFCHbKt5BCCEeUs2ebpPadz7koVGnwsK4Fy3VjCWnQVH8U7X9lGbFg-U7BjZz8_B1L3bLgfMrpSWxIscEaiewz-yF27PsmpEtU2/s1600/quick-tutorial-nodejs-app-service-azure+-+02+-+old+app+services+classification+-+Web+App+Api+App.png" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghj1ghRhP1wULQIJLP16kOOkI6C3wnac203J45b11zOzl7lixf6EsCN4K6cdCAaNXhkmpayls2DoSp2giPkyB8c3BSAMVQepTVsimKttO7Pc8gTTjMWoe8Zmkfq0gbUDGKKA_0-903h6T4/s1600/quick-tutorial-nodejs-app-service-azure+-+03+-+old+app+services+classification+-+Mobile+App.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghj1ghRhP1wULQIJLP16kOOkI6C3wnac203J45b11zOzl7lixf6EsCN4K6cdCAaNXhkmpayls2DoSp2giPkyB8c3BSAMVQepTVsimKttO7Pc8gTTjMWoe8Zmkfq0gbUDGKKA_0-903h6T4/s1600/quick-tutorial-nodejs-app-service-azure+-+03+-+old+app+services+classification+-+Mobile+App.png" class="screenshot-standard" /></a>
<br>
<br>
<h3>Creating an Azure App Service</h3>
Click on App Service in the left menu (1)
<br>
Then on Add on the top menu (2)
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisXtHRDt7YqC8r0LugWg2Cdcxgk8GAebkST5UfCASO_6c81qhliehbuEdgeso0b48h79i6BzUuNmOd03xf4bHh2QoLAQWlpLRqLrYh-0XxIjgBRH2v0I3e4G1lkiz4P8iFBjVjiwwb7MXO/s1600/quick-tutorial-nodejs-app-service-azure+-+04+-+create+app+service+step+1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisXtHRDt7YqC8r0LugWg2Cdcxgk8GAebkST5UfCASO_6c81qhliehbuEdgeso0b48h79i6BzUuNmOd03xf4bHh2QoLAQWlpLRqLrYh-0XxIjgBRH2v0I3e4G1lkiz4P8iFBjVjiwwb7MXO/s1600/quick-tutorial-nodejs-app-service-azure+-+04+-+create+app+service+step+1.png" class="screenshot-standard" /></a>
<br>
<br>
You land on the "Web App create" page and you have to chose or type:
<ol>
<li>
the subscription
</li>
<li>
the resource group
</li>
<li>
the name
</li>
<li>
the runtime stack (aka the environment)
</li>
<li>
the region (place of the Microsoft datacenter)
</li>
</ol>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh01O3Zn7kc9-QeXjapyWRHBVlFAXbeAlcqLMb3-BmoscK7-L1BZhAK_zOM_DjtqJcdmVpq2zpwgfXQSoXk8Z6yPGq7HEw64cqeVMq2nPFaD1nyx1ePgHE-WWZi-7-dqzugklMbeendoj_g/s1600/quick-tutorial-nodejs-app-service-azure+-+05+-+create+app+app+settings.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh01O3Zn7kc9-QeXjapyWRHBVlFAXbeAlcqLMb3-BmoscK7-L1BZhAK_zOM_DjtqJcdmVpq2zpwgfXQSoXk8Z6yPGq7HEw64cqeVMq2nPFaD1nyx1ePgHE-WWZi-7-dqzugklMbeendoj_g/s1600/quick-tutorial-nodejs-app-service-azure+-+05+-+create+app+app+settings.png" class="screenshot-standard" /></a>
<br>
<br>
For the Service Plan, click on create New and type a name
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2RHwyEoZVLRyadqRSC6P3ox3ZDBOkUc5BA27hbuJvyUM6TLyZ9-0mS8S0z20E4fLsA4tPWtVwWq2MCZnLki9EI6-OcGVcQV3qky6p2fvrUmShbzaRVdUGac_LFPGfU2TQ1AbhxS8NoLKz/s1600/quick-tutorial-nodejs-app-service-azure+-+06+-+create+app+app+new+service+plan+and+name.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2RHwyEoZVLRyadqRSC6P3ox3ZDBOkUc5BA27hbuJvyUM6TLyZ9-0mS8S0z20E4fLsA4tPWtVwWq2MCZnLki9EI6-OcGVcQV3qky6p2fvrUmShbzaRVdUGac_LFPGfU2TQ1AbhxS8NoLKz/s1600/quick-tutorial-nodejs-app-service-azure+-+06+-+create+app+app+new+service+plan+and+name.png" class="screenshot-standard" /></a>
<br>
<br>
then click on "change size" an on the opening pane, select "Dev/Test" and "Shared Infrastructure" because it is a tutorial and we take benefits of the free offer.
<br> (don't forget you gave your credit card refenreces and avoid bad surprises few weeks later...). Click on "Apply".
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3FvCp872bJPiGnMnxyp-PX18ESDjOBSinAe0QTeq_-Gz7056fX3wdjqNk71QH7QIcNEHS_BEurdZWJ6Rau9_2ylbhPKc_WY9lmx-glAT1Wj54zrHNRkgYiaJjJFC_fuTxDD0SeDqApP3S/s1600/quick-tutorial-nodejs-app-service-azure+-+07+-+create+app+app+new+service+plan+-+service+plan+size++dev+free.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3FvCp872bJPiGnMnxyp-PX18ESDjOBSinAe0QTeq_-Gz7056fX3wdjqNk71QH7QIcNEHS_BEurdZWJ6Rau9_2ylbhPKc_WY9lmx-glAT1Wj54zrHNRkgYiaJjJFC_fuTxDD0SeDqApP3S/s1600/quick-tutorial-nodejs-app-service-azure+-+07+-+create+app+app+new+service+plan+-+service+plan+size++dev+free.png" class="screenshot-standard" /></a>
<br>
<br>
You are led back to the review and create page. Click on "Review and Create".
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEhpwbePar7NngIg4xCMFnIT-5SwSeXog1dTU2ctqcaEtbVT3ZBqC70FnnqQss5nCfs0GQG1eWMwrnppNstvjLG8T6sP61p2o8XHP8bkKoWME-AMcz4FGdl0Yt_mL3zBH_cKzvYAjtwydf/s1600/quick-tutorial-nodejs-app-service-azure+-+08+-+create+app+app+new+service+plan+-+service+plan+size++dev+free+set.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEhpwbePar7NngIg4xCMFnIT-5SwSeXog1dTU2ctqcaEtbVT3ZBqC70FnnqQss5nCfs0GQG1eWMwrnppNstvjLG8T6sP61p2o8XHP8bkKoWME-AMcz4FGdl0Yt_mL3zBH_cKzvYAjtwydf/s1600/quick-tutorial-nodejs-app-service-azure+-+08+-+create+app+app+new+service+plan+-+service+plan+size++dev+free+set.png" class="screenshot-standard" /></a>
<br>
<br>
Click on "Create".
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9c9FlrdXCZASQo3kyovsVJhyW_BZjyU5uiowFC1GaysnmtFQXs7bohAnO6CoTH4yvntMMI2YHS0VZOIvUJWIqA8Pi4Hf8DQY6pVyp9wE9ycb4DZqNuiKLRrKjTICjzWjhOk232ktIDmPG/s1600/quick-tutorial-nodejs-app-service-azure+-+09+-+create+app+review+and+create.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9c9FlrdXCZASQo3kyovsVJhyW_BZjyU5uiowFC1GaysnmtFQXs7bohAnO6CoTH4yvntMMI2YHS0VZOIvUJWIqA8Pi4Hf8DQY6pVyp9wE9ycb4DZqNuiKLRrKjTICjzWjhOk232ktIDmPG/s1600/quick-tutorial-nodejs-app-service-azure+-+09+-+create+app+review+and+create.png" class="screenshot-standard" /></a>
<br>
<br>
The Web App creation is starting...
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDCzE3JCItketIhVZWiGnSx64X7yQfX43w3fEqHdGY62e2fq0xVUhE4VwC24l96k_4DrKkQmf2em6rGtZHtUYXiHsYlWdiXBBQ_hjRW32sQ4fQLy8Zxxx1Nv6BTGP62cF14A8-NsgvnOzq/s1600/quick-tutorial-nodejs-app-service-azure+-+10+-+deployment+started.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDCzE3JCItketIhVZWiGnSx64X7yQfX43w3fEqHdGY62e2fq0xVUhE4VwC24l96k_4DrKkQmf2em6rGtZHtUYXiHsYlWdiXBBQ_hjRW32sQ4fQLy8Zxxx1Nv6BTGP62cF14A8-NsgvnOzq/s1600/quick-tutorial-nodejs-app-service-azure+-+10+-+deployment+started.png" class="screenshot-standard" /></a>
<br>
<br>
You can see progressing steps...
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTJ5X2xR_f3G-afAlfL9Nk-skhqz9DMfQ3uKMomXe9MGtDkApbXdyS0kg49OEf6OkMJSJmSP6iVpPG13kYtsR4thV4wukugLryjHAerCfJKblzi0RgMa0y_yGzlEY7nI50CKoYnbxExfPh/s1600/quick-tutorial-nodejs-app-service-azure+-+11+-+create+app+-+deployment+running.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTJ5X2xR_f3G-afAlfL9Nk-skhqz9DMfQ3uKMomXe9MGtDkApbXdyS0kg49OEf6OkMJSJmSP6iVpPG13kYtsR4thV4wukugLryjHAerCfJKblzi0RgMa0y_yGzlEY7nI50CKoYnbxExfPh/s1600/quick-tutorial-nodejs-app-service-azure+-+11+-+create+app+-+deployment+running.png" class="screenshot-standard" /></a>
<br>
<br>
and finally, it is complete.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK0RW_U3oRtwMBHlqHNjjcjXrwwgGOGife6UyOJ53dW0ekPDYtWtf2glaOkOaH-SoDMwxvhnujNCkRBDhUTP6MdTAlJUFaCl5uci6GjlT4hKqqtu1coytvaZ_ffveCKLlPB0h6NYlqOd9B/s1600/quick-tutorial-nodejs-app-service-azure+-+12+-+create+app+-+deployment+complete.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK0RW_U3oRtwMBHlqHNjjcjXrwwgGOGife6UyOJ53dW0ekPDYtWtf2glaOkOaH-SoDMwxvhnujNCkRBDhUTP6MdTAlJUFaCl5uci6GjlT4hKqqtu1coytvaZ_ffveCKLlPB0h6NYlqOd9B/s1600/quick-tutorial-nodejs-app-service-azure+-+12+-+create+app+-+deployment+complete.png" class="screenshot-standard" /></a>
<br>
<br>
If you click on "Go to resource", you are led back to the Web App "Overview" page.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisDQ7QzH6N2gvPC9MTUq7EmQ2mLuxdsIhd3JhD4qqzEhnGHahldaQGmJ8AkbHFxfh_TwG3IW84eyNnUjfyTjmtEjNGgw62rtFogz7FIqoTfE75ebWokQbKrl0TXseZMAIGTcB9Vk-Lvi_Q/s1600/quick-tutorial-nodejs-app-service-azure+-+13+-+create+app+-+new+created+web+app+page+overview.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisDQ7QzH6N2gvPC9MTUq7EmQ2mLuxdsIhd3JhD4qqzEhnGHahldaQGmJ8AkbHFxfh_TwG3IW84eyNnUjfyTjmtEjNGgw62rtFogz7FIqoTfE75ebWokQbKrl0TXseZMAIGTcB9Vk-Lvi_Q/s1600/quick-tutorial-nodejs-app-service-azure+-+13+-+create+app+-+new+created+web+app+page+overview.png" class="screenshot-standard" /></a>
<br>
<br>
And you also can see the new Web App among the other ones in the "App Services" page.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrFpb9oyhA78Nz6xvmwVwTNnMneuxl2xQckcPormsy4szoPFIDz7qAuRdtmRiFbj7E2QDtN8Qz1pRQ-QDXOebxe4Jf9-Ng2I6wdusrwImfys1pzK2sND8WD3gAMJ8Bjnp-muyjxoB3S951/s1600/quick-tutorial-nodejs-app-service-azure+-+14+-+create+app+-+new+app+visible+as+a+resource.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrFpb9oyhA78Nz6xvmwVwTNnMneuxl2xQckcPormsy4szoPFIDz7qAuRdtmRiFbj7E2QDtN8Qz1pRQ-QDXOebxe4Jf9-Ng2I6wdusrwImfys1pzK2sND8WD3gAMJ8Bjnp-muyjxoB3S951/s1600/quick-tutorial-nodejs-app-service-azure+-+14+-+create+app+-+new+app+visible+as+a+resource.png" class="screenshot-standard" /></a>
<br>
<br>
Our Web App is created, we have now to deploy our Node JS API to it.
<br>
<br>
<h2 id="deployment">Node JS API deployment</h2>
We are now going to test a very cool feture of the new App Service: deploying code from a Github public repo:
<br>
Click on "Deployment center", scroll down and locate "External". Click on it.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqHRk6AcWeaACcFqkt_Db-nAYspeX5YA9YPQxPlKLoOp55XrSOa9SBil_dqIY8PR0JONgc4W-ue516ONRQA1v8VJJhqg0FNVUa27RJ2WBnxaSytjDXxvgbwDJtaXPxHK2BDchxGd_Ow5x0/s1600/quick-tutorial-nodejs-app-service-azure+-+15+-+code+deployment+-+deployment+center+-+external.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqHRk6AcWeaACcFqkt_Db-nAYspeX5YA9YPQxPlKLoOp55XrSOa9SBil_dqIY8PR0JONgc4W-ue516ONRQA1v8VJJhqg0FNVUa27RJ2WBnxaSytjDXxvgbwDJtaXPxHK2BDchxGd_Ow5x0/s1600/quick-tutorial-nodejs-app-service-azure+-+15+-+code+deployment+-+deployment+center+-+external.png" class="screenshot-standard" /></a>
<br>
<br>
Chose the App Service build service (Kudu), and click on "Continue"
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiSoBAwXgXwHte46wStbZPJd4WuoczpqJbIFAZsMc0H0b1ITaEwU-WOYarlyv-L2bZYhyphenhyphena0R0ALSFvIJR6w4yhs5dujWGzu1QT_rFuEfwJrkJlY5B7p1oTxGxmnz0ORtDLkCeb4emT_Riv/s1600/quick-tutorial-nodejs-app-service-azure+-+16+-+code+deployment+-+deployment+center+-+external+-+Kudu.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiSoBAwXgXwHte46wStbZPJd4WuoczpqJbIFAZsMc0H0b1ITaEwU-WOYarlyv-L2bZYhyphenhyphena0R0ALSFvIJR6w4yhs5dujWGzu1QT_rFuEfwJrkJlY5B7p1oTxGxmnz0ORtDLkCeb4emT_Riv/s1600/quick-tutorial-nodejs-app-service-azure+-+16+-+code+deployment+-+deployment+center+-+external+-+Kudu.png" class="screenshot-standard" /></a>
<br>
<br>
Fill the required field. This is the path to my Node.js API public repo:
<br>
https://github.com/MarcCharmois/app-service-api-node-contact-list
<br>
The branch is master
<br>
Select "Public", the field for the Credentials will disapear. Click on "Continue".
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwRt0OV4oqd1GjCea_Ah9QBs8tvGq19mb8Np9J0c1GZ242JxM6ZSeNTqcFCXTKOxES7Li4uPZKxXymu8Br-ArPR7PdS30OaKo8Asuahp9V4PR0RiRDhAveq2JI2euvfKT2mVTQ-_uGLJKf/s1600/quick-tutorial-nodejs-app-service-azure+-+17+-+code+deployment+-+deployment+center+-+external+-+Github+-++public+repo+-+repo+name.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwRt0OV4oqd1GjCea_Ah9QBs8tvGq19mb8Np9J0c1GZ242JxM6ZSeNTqcFCXTKOxES7Li4uPZKxXymu8Br-ArPR7PdS30OaKo8Asuahp9V4PR0RiRDhAveq2JI2euvfKT2mVTQ-_uGLJKf/s1600/quick-tutorial-nodejs-app-service-azure+-+17+-+code+deployment+-+deployment+center+-+external+-+Github+-++public+repo+-+repo+name.png" class="screenshot-standard" /></a>
<br>
<br>
Click on "Finish"
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXcaDYeyLMh0KJd5oBUjPaTcWnZ7DJYmpNFV_IfcxiGgE6JSXLvb0owlSYGkvyaAj9rqnizPpys6h18FAEN8aPBYjP9jFAFQ2euMk44yI9unQATr1306ve1p7zsgRIuYRPcza1TiVQ_oDD/s1600/quick-tutorial-nodejs-app-service-azure+-+18+-+code+deployment+-+deployment+center+-+external+-+finish.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXcaDYeyLMh0KJd5oBUjPaTcWnZ7DJYmpNFV_IfcxiGgE6JSXLvb0owlSYGkvyaAj9rqnizPpys6h18FAEN8aPBYjP9jFAFQ2euMk44yI9unQATr1306ve1p7zsgRIuYRPcza1TiVQ_oDD/s1600/quick-tutorial-nodejs-app-service-azure+-+18+-+code+deployment+-+deployment+center+-+external+-+finish.png" class="screenshot-standard" /></a>
<br>
<br>
The deployment is starting...
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyAqOGA0ALjhvHPEGqnkfS0WOxkmL6xWyXqNwpAYXZveXS4loc12VJpGzPs0_FoKuENTG0XhOL6vVKlkzYkiR60GfYkLoXN7nsNNv3RdUhOmvioduJSjuobXAZ9apZ3EMH6mN6Dn80X4_/s1600/quick-tutorial-nodejs-app-service-azure+-+19+-+code+deployment+-+deployment+center+-+external+deployment+starting.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyAqOGA0ALjhvHPEGqnkfS0WOxkmL6xWyXqNwpAYXZveXS4loc12VJpGzPs0_FoKuENTG0XhOL6vVKlkzYkiR60GfYkLoXN7nsNNv3RdUhOmvioduJSjuobXAZ9apZ3EMH6mN6Dn80X4_/s1600/quick-tutorial-nodejs-app-service-azure+-+19+-+code+deployment+-+deployment+center+-+external+deployment+starting.png" class="screenshot-standard" /></a>
<br>
<br>
...then complete. You can see the last commit message I have done in GitHub. The Web App (especially Kudu) can realy behave as a source code management. We have done a git fetch from the Azure Web App pointing to a github public repo!
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinB71CNWbtMmbh01rHDi1sg5X_yC3dbJBzpv3bsOhpwBXWeRQ8CrsEjAH6t65_HP4Vs0_v39360KWVju0aZ4D2CUTRzjbI3U6J3Oa0QD1YKt0Yl_DQ29bZaV27xk0kRTrMGw-nBzsoricd/s1600/quick-tutorial-nodejs-app-service-azure+-+20+-+code+deployment+-+deployment+center+-+external+-+deployment+complete.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinB71CNWbtMmbh01rHDi1sg5X_yC3dbJBzpv3bsOhpwBXWeRQ8CrsEjAH6t65_HP4Vs0_v39360KWVju0aZ4D2CUTRzjbI3U6J3Oa0QD1YKt0Yl_DQ29bZaV27xk0kRTrMGw-nBzsoricd/s1600/quick-tutorial-nodejs-app-service-azure+-+20+-+code+deployment+-+deployment+center+-+external+-+deployment+complete.png" class="screenshot-standard" /></a>
<br>
<br>
Now our code is deployed, time is to testing it!
<br>
<br>
<h2>Testing the deployment</h2>
Go back to the Overview page of your Web App. Click on the Web App Url :
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgney3xT0j5Vj8-wCK-W_CumeA_pP0O-v14Q5De_fOekdw0svdET9-Bwkho3zsYQoKxpeO2guDXITyC0-mIAOoLkgEnIPv26roZS8h1boYeBFbLYOiSGCTuQQJ-YmZPDxBw-ML5SblNPEX1/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-+testing+external+deployment+-+Wep+App+Overview.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgney3xT0j5Vj8-wCK-W_CumeA_pP0O-v14Q5De_fOekdw0svdET9-Bwkho3zsYQoKxpeO2guDXITyC0-mIAOoLkgEnIPv26roZS8h1boYeBFbLYOiSGCTuQQJ-YmZPDxBw-ML5SblNPEX1/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-+testing+external+deployment+-+Wep+App+Overview.png" class="screenshot-standard" /></a>
<br>
<br>
The API "/" root is displaying. I customized the Welcome page of the Web App of "Try Azure App Service" and added some links regarding our API.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB-f_qZ0nEG6peK3G-R0EJ13aIWbX43CtyehCYkiVe7OaflEvducaE-Ud_HIAgYPVCbrIP4O89QsDf3bAol5QitT_1DEuK_PzAo7OaM73FdNyk78bjiHUl1A4ZkA4NVhPbyVr8yhqPy2s-/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-+testing+external+deployment+-+Wep+App+welcome+page.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB-f_qZ0nEG6peK3G-R0EJ13aIWbX43CtyehCYkiVe7OaflEvducaE-Ud_HIAgYPVCbrIP4O89QsDf3bAol5QitT_1DEuK_PzAo7OaM73FdNyk78bjiHUl1A4ZkA4NVhPbyVr8yhqPy2s-/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-+testing+external+deployment+-+Wep+App+welcome+page.png" class="screenshot-standard" /></a>
<br>
<br>
But if you click on the "See Contacts" button you see your API sending the contacts in JSON format
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqzT6_3WWniOtwveSn4HivUAq2B0kg9zB_uqer-soT4VyrVniFmE5oJA3O9VXsf0veDgFeFNnFHN8kGnzw1lphqMMZ7lpxKUv2EvGjY9V7erNj7_HP2Yp-4b2FQquWBByVvDa1mz4y1tHK/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+Contacts+displaying.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqzT6_3WWniOtwveSn4HivUAq2B0kg9zB_uqer-soT4VyrVniFmE5oJA3O9VXsf0veDgFeFNnFHN8kGnzw1lphqMMZ7lpxKUv2EvGjY9V7erNj7_HP2Yp-4b2FQquWBByVvDa1mz4y1tHK/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+Contacts+displaying.png" class="screenshot-standard" /></a>
<br>
<br>
So it works! Notice that, we have never done any environment configuration operations to tell the Web App of the Azure App Service that we were planning to deploy a Node.js API to it.
<br>What is fantastic regarding a Web App of Azure App Service, is, it is "smart enough" to "understand" that we were deploying a Node.js API and that it could adapt itself to make the API run. By the way you can see in my source code files a iisnode.yml file and a web.config file. I add them to be able to deploy an API manually <a href="https://mosshowto.blogspot.com/2017/10/try-azure-app-service.html">in this other post</a>. But assume these 2 files are not in my GitHub repo, if we make the same deployment that we just did without these 2 files, you would have seen these 2 files anyway. The Kudu build engine would have created them to make the API work!
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFt6ZT3ynpU7qwnRtCFT28j8f1tvPA9KybTkSipYAsnfPWm4AwL54DyljryEMFQ9QIoBHz9RNyyNB4dAy0OhFD8xPykZKenur-SXvCjP3bxjygdSoUUcX0CtK4XTz0M5lmm-jSewSQDVZV/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-Check+the+deployed+files+with+Kudu.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFt6ZT3ynpU7qwnRtCFT28j8f1tvPA9KybTkSipYAsnfPWm4AwL54DyljryEMFQ9QIoBHz9RNyyNB4dAy0OhFD8xPykZKenur-SXvCjP3bxjygdSoUUcX0CtK4XTz0M5lmm-jSewSQDVZV/s1600/quick-tutorial-nodejs-app-service-azure+-+21+-Check+the+deployed+files+with+Kudu.png" class="screenshot-standard" /></a>
<br>
<br>
<H2>Using Swagger UI</H2>
If you want to have a more complete testing experience using swagger, click on the "Use Swagger" button on the Welcome page, or type this Url:
<br>
<br>
https://<your app service url>/docs
<br>
in my case:
<br>
https://test-nodejs2.azurewebsites.net/docs
<br>
<br>
The Swagger UI display your API features:
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRcugmEtkPVXMlfnC1AjRj-DFq3yQxj5bRjMq5ZZWNZukCw_-jxCaHqLqr0CU0N_552D5g6K6U9durtQYLBVfPBMI4s_8gEAL15tlOQST7or8kLxsPyB0MJzsGJ-3iFiRIuFAG_j1HaDya/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+swagger.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRcugmEtkPVXMlfnC1AjRj-DFq3yQxj5bRjMq5ZZWNZukCw_-jxCaHqLqr0CU0N_552D5g6K6U9durtQYLBVfPBMI4s_8gEAL15tlOQST7or8kLxsPyB0MJzsGJ-3iFiRIuFAG_j1HaDya/s1600/quick-tutorial-nodejs-app-service-azure+-+22+-+testing+external+deployment+-+Wep+App+swagger.png" class="screenshot-standard" /></a>
<br>
<br>
Click on "Contacts" to display the 2 API routes
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrZ7ZXB5docoFFjNByxlTCYG6pM59gyhv9ViZ4_DCYmigc9UqKKq41FgFkd0AKAGu7JezDVVQA5U9N_5Y9DazUH1wlqnM8t86GIkw8wOyUhn5ouoAVhZZXDGqfIWKeTP7mg7_09qh4ELKz/s1600/quick-tutorial-nodejs-app-service-azure+-+24+-+testing+external+deployment+-+Wep+App+swagge+testing+1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrZ7ZXB5docoFFjNByxlTCYG6pM59gyhv9ViZ4_DCYmigc9UqKKq41FgFkd0AKAGu7JezDVVQA5U9N_5Y9DazUH1wlqnM8t86GIkw8wOyUhn5ouoAVhZZXDGqfIWKeTP7mg7_09qh4ELKz/s1600/quick-tutorial-nodejs-app-service-azure+-+24+-+testing+external+deployment+-+Wep+App+swagge+testing+1.png" class="screenshot-standard" /></a>
<br>
<br>
Test the first route by clicking on it.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUKw0DbYh79lP9ueC9xFABOfQK5QpacOI3B-TbJIlpDmpqbZD4KXVbFTyI5YI54DYW3exci9Gd_9Dzdcdl1lOSBh-nnMzwuSO-FrC20xHz9_qJPUmwSL-Poiq5ywcarCT7tF0Xgx3Y7G1r/s1600/quick-tutorial-nodejs-app-service-azure+-+25+-+testing+external+deployment+-+Wep+App+swagge+testing+2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUKw0DbYh79lP9ueC9xFABOfQK5QpacOI3B-TbJIlpDmpqbZD4KXVbFTyI5YI54DYW3exci9Gd_9Dzdcdl1lOSBh-nnMzwuSO-FrC20xHz9_qJPUmwSL-Poiq5ywcarCT7tF0Xgx3Y7G1r/s1600/quick-tutorial-nodejs-app-service-azure+-+25+-+testing+external+deployment+-+Wep+App+swagge+testing+2.png" class="screenshot-standard" /></a>
<br>
<br>
and clicking on "Try it out!":
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPkJ1qtWLeO-3W1UZeHIk9RliaYGwQLJSUkzi8vtzkewHoWGcWQSha4hpHpeqQdVidAzsSV-VbFc1sqa1gVrvQSwyGL1fEhdp60hDAlW1xIz__wZBNe6loF28OkNh0SkWF6D_tJCS3gNIL/s1600/quick-tutorial-nodejs-app-service-azure+-+26+-+testing+external+deployment+-+Wep+App+swagge+testing+3.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPkJ1qtWLeO-3W1UZeHIk9RliaYGwQLJSUkzi8vtzkewHoWGcWQSha4hpHpeqQdVidAzsSV-VbFc1sqa1gVrvQSwyGL1fEhdp60hDAlW1xIz__wZBNe6loF28OkNh0SkWF6D_tJCS3gNIL/s1600/quick-tutorial-nodejs-app-service-azure+-+26+-+testing+external+deployment+-+Wep+App+swagge+testing+3.png" class="screenshot-standard" /></a>
<br>
<br>
<h2>
Keep developping online within Azure</h2>
<br>
Last, you can enjoy the preview of Visual Studio Code online or App Service Editor for keeping developping your API without having to deploy anymore from local environment.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7vK5PGO1HoR5FU0va_lVcdP0mkfWT-yvV25lnhj1Q8HEdHSA3mbSTchORD7L9yX8dMifmXxlzDyL6cWzeb3sW5ydzTuRxcq-3-B_4TNnWUBBVMseV2GILVCpf5vblamCgQGCDQDRrhZ5C/s1600/quick-tutorial-nodejs-app-service-azure+-+27+-+keep+developping+online+-+App+Service+Editor.png.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7vK5PGO1HoR5FU0va_lVcdP0mkfWT-yvV25lnhj1Q8HEdHSA3mbSTchORD7L9yX8dMifmXxlzDyL6cWzeb3sW5ydzTuRxcq-3-B_4TNnWUBBVMseV2GILVCpf5vblamCgQGCDQDRrhZ5C/s1600/quick-tutorial-nodejs-app-service-azure+-+27+-+keep+developping+online+-+App+Service+Editor.png.png" data-original-width="1600" class="screenshot-standard" /></a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuCwD2dlyYYmhEPEopZVXVvYmIOsCHDXUNO9PNOgm-P4ahT_d7zMtFqiqHrdbuw66c_cP4JbHnjJt8qWCWacFIbfHFt8EPsIAlxt9dgsxbQ7_SPh_CdrTjxkUcJatIvyVB6mFirYffSxiL/s1600/quick-tutorial-nodejs-app-service-azure+-+28+-+keep+developping+online+-+App+Service+Editor.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuCwD2dlyYYmhEPEopZVXVvYmIOsCHDXUNO9PNOgm-P4ahT_d7zMtFqiqHrdbuw66c_cP4JbHnjJt8qWCWacFIbfHFt8EPsIAlxt9dgsxbQ7_SPh_CdrTjxkUcJatIvyVB6mFirYffSxiL/s1600/quick-tutorial-nodejs-app-service-azure+-+28+-+keep+developping+online+-+App+Service+Editor.png" class="screenshot-standard" /></a>
<br>
<br>
By the way, it is an excellent way to check what was exactly deployed into the Azure App Service.
<br>
I was really impressed to see that an API developped 2 years ago can still work so well and be deployed so easily.
<br>
<br>
Hope that helps :-)
<br>
<br>
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com4tag:blogger.com,1999:blog-4357140756496246910.post-17255463520960388012017-10-06T14:43:00.002+02:002019-09-13T14:40:12.186+02:00Azure App Service<style>
.left-half {
width: 46%;
float: left;
/*border:solid 1px silver;*/
border-right: solid 1px silver;
margin-right: 6px;
padding: 5px;
}
.right-half {
width: 46%;
float: left;
/*border:solid 1px silver;*/
border-bottom: 0;
border-left: 0;
margin-left: 6px;
padding: 5px;
}
@media screen and (max-width: 1024px) {
.left-half {
width: 100%;
float: left;
border: solid 1px silver;
margin: 0px;
padding: 3px;
}
.right-half {
width: 100%;
float: left;
border: solid 1px silver;
margin: 0px;
padding: 3px;
}
}
.embed-container {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
max-width: 100%;
}
.embed-container iframe,
.embed-container object,
.embed-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
<span style="color:red">Updated 2019 sept. 3rd</span>
<br />
Topic : An update on Azure App Service offering, available from summer 2018. Here are some
explanations, details and useful links
<br>
<br>
<h2>A little bit of history: </h2>
<div class="left-half" style="margin-right:3px;">
<b>2015- Summer 2018</b>
<br>
<b>First simplification : Creation of the App Service offering that gathers Web App, API App, Mobile Back-end,
Logic App and Function.</b>
<br>
<br />
Before 2015, for Azure classic portal, there was 2 offerings - Azure Websites and Azure Mobile services.
<br>Since the beginning of 2015 and in Azure new portal, both of them got rolled into something called Azure App
Service which also included two more kinds of apps - API Apps and Logic Apps. Recently a new App Service the
Function has joined the Microsoft Azure App Service offering
<br />
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj6I1fRhO6DkSlB8Vdy9pVIjBAysDkiBHEcaQbT0G6QNMNwVdbsSaRF1Owz8eXvAn-QMj3_ApIkZbxEt0N3rxVtBK49_ONOKM2qucm4VZzhyphenhyphenqMzGdhmm6ufj-I2Q02nerlnFVNzBQG6Aqv/s1600/The+5+types+of+App+Services+available+in+Microsoft+Azure.png"
imageanchor="1"><img border="0" style="width:98%"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj6I1fRhO6DkSlB8Vdy9pVIjBAysDkiBHEcaQbT0G6QNMNwVdbsSaRF1Owz8eXvAn-QMj3_ApIkZbxEt0N3rxVtBK49_ONOKM2qucm4VZzhyphenhyphenqMzGdhmm6ufj-I2Q02nerlnFVNzBQG6Aqv/s1600/The+5+types+of+App+Services+available+in+Microsoft+Azure.png" /></a>
<br>
<h2>2015 General presentation</h2>App Service is a new offering for Azure wich pull in bunch of services into a
single offering called App Service including Web Apps, mobile, API and Logic. It is a new way in Azure to gather
different sevices so as they can enjoy the same capabilities. All the new features what we had in Azure Web
Sites are available across all for new type of services (mobile, API and Logic). That includes: <br />
<ul>
<li>How they are scaled</li>
<li>How they behave</li>
<li>Things like application insights</li>
</ul>
</div>
<div class="right-half" style="margin-left:3px;">
<b>Summer 2018- now (2019)</b>
<br>
<b> Second simplification. The App Service offering becomes even more simple :
<ul>
<li> Web App, API App, Mobile back-end, everything become a Web App.</li>
<li>Arrival of the Container (sept. 2017 Linux).</li>
<li>Logic App and Function become serverless App</li>
</ul></b>
Since 2018, looking at the 2019 Microsoft welcome page for App Service, we have now rather the choice between
Web Apps, Web App for Containers and API apps (<span style="color:red">1</span>).
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVOXfkOUJBbrvpkKNbeBmHU9JLZK-ucEh5HlPkqXuodg1qVBzgKjUp5MWjrEarGTQmZddhteB9QXJ2OdvIS_SXiOEl1Rf3bltWs1_j6Qlw9SVX-96MMB47jtNNPHyOHMeVEMW55-bGJBdb/s1600/Azure-App-Service+-+00+-+Welcome+1.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVOXfkOUJBbrvpkKNbeBmHU9JLZK-ucEh5HlPkqXuodg1qVBzgKjUp5MWjrEarGTQmZddhteB9QXJ2OdvIS_SXiOEl1Rf3bltWs1_j6Qlw9SVX-96MMB47jtNNPHyOHMeVEMW55-bGJBdb/s1600/Azure-App-Service+-+00+-+Welcome+1.png"
style="width:98%" /></a>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5L7HesMCGh_baMa1Q_PfX8_eQ2pQ1IzAlkCa72tM0C5BdtYZ5KTagCN57xKTthiUDeqiMhmbp5B10T-1dMKPwF79-XNLLX7m5pHerCf0eH7Q_SgW38F8ZBMduJFWxbSTXTcfn7XaAZU7D/s1600/Azure-App-Service+-+01+-+Welcome+2.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5L7HesMCGh_baMa1Q_PfX8_eQ2pQ1IzAlkCa72tM0C5BdtYZ5KTagCN57xKTthiUDeqiMhmbp5B10T-1dMKPwF79-XNLLX7m5pHerCf0eH7Q_SgW38F8ZBMduJFWxbSTXTcfn7XaAZU7D/s1600/Azure-App-Service+-+01+-+Welcome+2.png"
style="width:98%" /></a>
<br>
We will see bellow that the API App seems to be technically included in the Web App feature. The API App
category seems to have been kept for marketing reasons only.
<br>
Logic App and Azure Functions seem to have been removed from the App Service offering, although they are still
mentioned in the Microsoft App Service documentation as serverless Apps, but not very visible...(<span
style="color:red">2</span>).
<br>
</div>
<div style="clear:both"></div>
useful links:
<br>
<a href="https://azure.microsoft.com/en-in/services/app-service/">Link to Microsoft App Service Portal</a>
<br />
<a
href="https://mva.microsoft.com/en-US/training-courses/deep-dive-into-azure-app-service-a-platform-to-build-modern-applications-16828?l=vIBh1KR4C_8504668937">Fantastic
training courses on Azure from Microsoft including App Services</a><br />
<br />
<!-- More details -->
<h2>More details</h2>
<div class="h2-paragraph">
As written above, for App Service creation in the portal and as mentionned in this <a
href="https://docs.microsoft.com/en-us/azure/app-service/overview">other Microsoft doc</a>, it seems to have
actually no more disctintion between Web Apps, Api Apps and Web App for Containers, everything has become a Web
App. You have to chose at creation between Web App for code or Web App for Container but no choice reagrding Web
App or API App.
Thus, regarding the global name, create an App Service comes back to create a Web App since we have now, no more
other choice left, using the "App Services" left menu item in Azure Portal.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhih2uKTnzVyFkoRXHkRtftdIH7Pq5m-ftMZLh2wd-0sp2cHDxafNiz18nNCM7zhCnucKDdmBJaFMWKjCO_NLTwyWkSGaqgnze-Mm-haLPTPDB4ausp4t33lIyS9_VjJs6QAYSOSk_J44fm/s1600/Azure-App-Service+-+03+-+app+service+creation.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhih2uKTnzVyFkoRXHkRtftdIH7Pq5m-ftMZLh2wd-0sp2cHDxafNiz18nNCM7zhCnucKDdmBJaFMWKjCO_NLTwyWkSGaqgnze-Mm-haLPTPDB4ausp4t33lIyS9_VjJs6QAYSOSk_J44fm/s1600/Azure-App-Service+-+03+-+app+service+creation.png"
style="width:98%" /></a>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVc_X90EBV6qb7vo6rCYtOPQ-IXg1imMuB9hvj0dQ8ZZCybLcfWLnBngELRpL-1qXHIXBP8f8EkcPZxxAD3CgiapT62e7FmqCMIt8WqeMCcDcazeC7Gzb0BRYXZoy0klNd3vPpoE9nFCr0/s1600/Azure-App-Service+-+04+-+app+service+creation.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVc_X90EBV6qb7vo6rCYtOPQ-IXg1imMuB9hvj0dQ8ZZCybLcfWLnBngELRpL-1qXHIXBP8f8EkcPZxxAD3CgiapT62e7FmqCMIt8WqeMCcDcazeC7Gzb0BRYXZoy0klNd3vPpoE9nFCr0/s1600/Azure-App-Service+-+04+-+app+service+creation.png"
style="width:98%" /></a>
<br>
<br>
For sumarizing, in 2019 App Service = Web App, and Web App can host everything: Web Applications (Web Sites),
API, Mobile Back-end and Container. Furthermore, New Web App can
<ul>
<li> be based on any environement (Windows, Linux),</li>
<li>any techno, (.Net, PHP, Python, Node.js, etc.),</li>
</ul>
Logic App and Azure Functions seem to have been removed from the App Service offering, although they are still
mentioned in the Microsoft App Service documentation as serverless Apps, but not very visible...(see <span
style="color:red">2</span> at first screenshot).
<br> And even if, when creating a Function, it still appears in the App Service section of the portal.
<br>
<br>
</div>
<!-- Microsoft Azure Mobile App Service -->
<h2>Regarding the Mobile App</h2>
<div class="h2-paragraph">
<span style="background-color:yellow">Mobile App (back-end API) is deprecated</span> although the creation is
still available in the portal, but a message warns you that this feature will be removed on 2019 November 11.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1RuQJ0h1VsdzofbXJE4HZS3pWBhIoMNEil0sEbX1Wf7CHfzLO3HH8u1aIjHwuauSWHv6TTbm5R_RQ_xBiiE0389qARPgu3dFjTx7TCLx7riUCgYTwqU1YaYtlTidIjFx7Q31dL6E_e6sm/s1600/Azure-App-Service+-+05+-+mobile+app+deprecated.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1RuQJ0h1VsdzofbXJE4HZS3pWBhIoMNEil0sEbX1Wf7CHfzLO3HH8u1aIjHwuauSWHv6TTbm5R_RQ_xBiiE0389qARPgu3dFjTx7TCLx7riUCgYTwqU1YaYtlTidIjFx7Q31dL6E_e6sm/s1600/Azure-App-Service+-+05+-+mobile+app+deprecated.png"
style="width:100%" /></a>
<br>
<br>
<span style="background-color:yellow">The name Mobile App still remains but refers now to a global offering to:</span>
<ul>
<li>create Applications on mobile device + </li>
<li>create the back-end in Azure for the mobile application (that is an App Service) +</li>
<li>solutions for the other concerns (storage, authentication, push notifications)</li>
</ul>
This was the key benefits of the App Service Mobile App feature in 2015. There are still relevant but has to be seen as a
global offering and no more as an App Service.<br />
Accelerate your mobile app development with this turnkey way to structure storage,
authenticate users, and send push notifications.
<br>
With native and cross-platform SDKs for iOS, Android, Windows, and HTML, as well as a powerful and flexible REST
API, Mobile Apps empowers you to build
<br>
connected applications for any platform and deliver a consistent experience across devices.<br />
<br />
Integrate with SQL, Oracle, SAP, MongoDB, and more.<br />
Make your app work offline and sync.<br />
Connect to on-premises data.<br />
Leverage enterprise single sign-on with Active Directory.<br />
Integrate with social providers like Facebook, Twitter, and Google.<br />
Broadcast push notifications across platforms, with customer segmentation.<br />
Gain insights with mobile analytics.<br />
Auto-scale to millions of devices.<br />
source : Azure Portal Description when attempting to create
<br />
<br>
Here is an old video about Mobile App from 2015:
<br>
<div class="videoWrapper">
<video poster="https://sec.ch9.ms/ch9/1f0c/84c2e713-3e69-40d3-9097-9b1f09981f0c/mobileapps_960.jpg"
controls="true" onerror="ch9.functions.html5Presenter.fallback(this);"
oncanplay="ch9.functions.html5Presenter.html5Loaded(this);">
<source src="https://sec.ch9.ms/ch9/1f0c/84c2e713-3e69-40d3-9097-9b1f09981f0c/mobileapps_mid.mp4"
type="video/mp4" data-quality="Medium" onerror="ch9.functions.html5Presenter.fallback(this);">
<source src="https://sec.ch9.ms/ch9/1f0c/84c2e713-3e69-40d3-9097-9b1f09981f0c/mobileapps.webm"
type="video/webm" data-quality="Medium" onerror="ch9.functions.html5Presenter.fallback(this);">
<source src="https://sec.ch9.ms/ch9/1f0c/84c2e713-3e69-40d3-9097-9b1f09981f0c/mobileapps_high.mp4"
type="video/mp4" data-quality="High" onerror="ch9.functions.html5Presenter.fallback(this);">
<source src="https://sec.ch9.ms/ch9/1f0c/84c2e713-3e69-40d3-9097-9b1f09981f0c/mobileapps.mp4"
type="video/mp4" data-quality="Low" onerror="ch9.functions.html5Presenter.fallback(this);">
</video>
</div>
<div class="screenshot-large"
style="margin-top:-6px;font-size:11px;margin-left:0px;text-align:right;padding-right:20px;">Microsoft Azure
Mobile App Service Presentation - Azure Friday, (03-19-2015)</div>
<div style="clear:both"></div>
Useful links for <b>Mobile App global offering:</b>
<br>
<a href="https://azure.microsoft.com/en-us/documentation/learning-paths/appservice-mobileapps/">Link to Azure
Mobile Apps documentation</a><br />
<a
href="https://azure.microsoft.com/en-us/resources/videos/azure-app-service-mobile-apps-with-kirill-gavrylyuk/">Link
to Azure Friday Video - Azure App Service Mobile Apps with Kirill Gavrylyuk</a><br />
<a href="https://azure.microsoft.com/en-in/services/app-service/mobile/">Link to Mobile App Microsoft Portal
</a>
<br />
The <a
href="https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-nodejs-mongodb-app">Microsoft
documentation for Node.js backend with Mongo DB has changed</a>
</div>
<br />
<!-- Try Azure App Service -->
<h2> "Try Azure App Service"</h2>
<div class="h2-paragraph">
<span style="background-color:yellow">
Want to play with Azure Portal and Azure App Services for free (no credit card information needed by Microsoft, just a social account for signing)?
<a href="https://azure.microsoft.com/en-us/try/app-service/" target="blank">Go there:</a></span>
<br>
<br>
<a href="https://azure.microsoft.com/en-us/try/app-service/" target="blank">
<img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuF7F9ABDE7Uy2UneF2mDe2ITSU-Nwh6UAj2TKm793rCjWryMs8Kl3WZxKn1ehMAEzJg7292JXtylXfELMSUuwv4Q1C1tygeSxSU9Cj-6vByf_yuaAQrRlSM1QbaipRTSVCfSI-qssGSZY/s1600/Azure-App-Service+-+06+-+Try+Azure+App+Service.png" style="width:100%" /></a>
<br>
<br>
By the way, you can notice that, in "Try Azure App Service", you can only chose between Web App and Web App for
Containers and that, thus, Web App and API App has become the same thing.
<br>From summer 2018, the only resource running an application (Web site, API, Mobile Backend, Container) in
Azure App Services, is the Web App .
<br>
You can also notice that serverless Apps (Logic App, Function) has been removed from the App Service offering.
<br>
<br>
</div>
<!-- The new types of App Service -->
<h2>The new types of App Service : Web Apps (API Apps), Web App for Containers, (Serverless App)</h2>
<div class="h2-paragraph">
<!--Web Apps -->
<h3>Web App</h3>
<img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4wb5-0pQEbWoedSpiGhuuKCJTIe747HR5p5ufs1lmB4ieajFZ6YjeQ4N0A68dS2lKxfz-_JGzLH_1IfXNx2nbFjM_chG7VvkX7tlSIIK6IgzBea_7o4NOmDH0768pGmPfZ6lzzN6fOtwT/s1600/download.png"
data-original-width="123" data-original-height="123" style="margin-left:13px;margin-top:-10px;width:40px" />
<br />
Azure App Service is an HTTP-based service for hosting web applications, REST APIs, and mobile back ends. You
can develop in your favorite language, be it .NET, .NET Core, Java, Ruby, Node.js, PHP, or Python. Applications
run and scale with ease on both Windows and Linux-based environments<br />
source: <a href="https://docs.microsoft.com/en-us/azure/app-service/overview">Microsoft App Service overview</a>
<br />
Create and deploy mission-critical web applications that scale with your business
<ul>
<li>Supports Windows and Linux platforms</li>
<li>Built-in autoscale and load balancing</li>
<li>High availability with auto-patching</li>
<li>Continuous deployment with Git, Team Foundation Server, GitHub and DevOps</li>
<li>Supports WordPress, Umbraco, Joomla! and Drupal</li>
</ul>
<ul>
<li>
<b>Jumpstart your app building</b><br>
Get your web apps into users’ hands faster using .NET, Java, Node.js, PHP and Python on Windows or .NET
Core, Node.js, PHP or Ruby on Linux. Use a fully-managed platform to perform OS patching, capacity
provisioning, servers and load balancing. Configure from CLI or the Azure portal or use prebuilt
templates to achieve one-click deployment.
</li>
<li>
<b>Increase developer productivity</b><br>
Start fast and finish faster with source code integration from GitHub, live debugging and one-click
publish directly from Microsoft Visual Studio IDE. Easily connect to your database of choice and tap
into an ecosystem of OSS packages, APIs, connectors and services through the Azure Marketplace,
expediting development. Quickly add custom domains and SSL, single sign-on (SSO) integration with
popular identity providers and application health monitoring to your apps with the Azure portal.
</li>
<li>
<b>Ship updates faster</b><br>
Automate deployments with continuous integration/continuous deployment (CI/CD) capabilities using
DevOps, Bit Bucket and GitHub. App Service creates an association with the selected repository, so your
apps are updated each time your source code changes. Schedule performance and quality tests with staging
environments, use deployment slots to swap staging to production in seconds and roll back to previous
versions without downtime.
</li>
<li>
<b>Achieve global scale on demand</b><br>
Get high availability within and across Azure regions as you deploy data and host services across
multiple locations with one mouse click. Automatically scale vertically and horizontally based on
application performance or customisable rules to handle peaks in workload automatically while minimising
costs during off-peak times. Meet the most rigorous app performance and scalability requirements with
the newly introduced D-Series compute option.
</li>
<li>
<b>Get actionable insights and analytics</b><br>
View application performance and health end to end, so you can make the decisions that improve your
business. Azure Monitor provides detailed views of resource usage, while Application Insights provides
deeper insights into your app’s throughput, response times, memory and CPU utilisation and error trends.
</li>
<li>
<b>Take advantage of hybrid consistency</b><br>
Get a flexible and unified approach to building and managing apps that can run across both the cloud and
on-premises. Deploy your apps to App Service in your cloud of choice—Azure, Azure national clouds or
even on-premises with Azure Stack. Securely run your apps in your Azure Virtual Network at large scale
with enhanced privacy, power and performance using an App Service Environment.
</li>
<li>
<b>Choose enterprise-grade services</b><br>
Host your apps on a highly-secure cloud platform that complies with ISO information security standards,
SOC2 accounting standards and PCI security standards and count on App Service to deliver on
enterprise-level SLA. Use Azure Active Directory (AD), as well as other popular identity providers, to
authenticate and authorise app access. Azure AD provides identity management and secured single sign-on
(SSO) integration with thousands of cloud SaaS applications such as Office 365, Salesforce, Dropbox and
Concur.
</li>
</ul>
<br />
<br />
<div class='embed-container'>
<iframe src='https://www.youtube.com/embed/jCfJWYocz1M' frameborder='0' allowfullscreen></iframe>
</div>
<br>
<!--Web Apps for containers -->
<h3>Web App for Containers</h3><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvQNeJ8uZcG9l-yarAA5qH3Z28H9L6dUlE4DIrabdbTFbRa7E0f-2TpXhsmkmOMp8A0btPyNLHkXEWSru3d_qWt-Y-Ee5CXJWWstx01FaYTGVF_38kQjeGF5lOKpgkNQz169Q-k-aLvOeI/s100/Azure-App-Service+-+07+-+Web+App+For+Containers.png"
style="margin-left:10px;margin-top:-13px;width:40px" /><br />
<br>
I have tested these Web Apps. First thing to know:
<ul>
<li>It is free for a Linux stack but you have to pay for a Windows one</li>
<li>It is not available for all regions</li>
<li>When created, the icon in the portal is exactly the same than for the other Web Apps (only API App kept
a different icon)</li>
</ul>
When familiarized with Docker that doesn't take much time, it is amazingly easy to deploy a container in these Web App through the portal. You can practice with this tutorial: <a href="https://mosshowto.blogspot.com/2019/09/build-docker-image-deploy-webapp.html">Build locally a docker image and deploy it to an Azure Web App for containers</a>
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMXTwyraWefxuyrZvg3qaQEUHY25G4IYqZiIxWYXqGLSCQCatgTTwWVZy2io1hUvthZ74t6F8tMCF7vtEDHjFm0722SVUZF01IMtjNhsyRLwBbPjJfQlgpNqAFRRH3A6dcaeJIFgt2YQTI/s1600/Azure-App-Service+-+08+-+Web+App+For+Containers+created.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMXTwyraWefxuyrZvg3qaQEUHY25G4IYqZiIxWYXqGLSCQCatgTTwWVZy2io1hUvthZ74t6F8tMCF7vtEDHjFm0722SVUZF01IMtjNhsyRLwBbPjJfQlgpNqAFRRH3A6dcaeJIFgt2YQTI/s1600/Azure-App-Service+-+08+-+Web+App+For+Containers+created.png"
style="width:100%" /></a>
<br>
<br>
<div class='embed-container' style="margin-left:5px">
<iframe src='https://www.youtube.com/embed/Fe_AYBD5m0I' frameborder='0' allowfullscreen></iframe>
</div>
<br>
<h3>API App</h3>
<img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAoKsDXPZxeYMWX74yF2Ic9W6OF2SIfKTip4ShALgVfA7snsYzqbf5-Lb5ZkDJsZJzNlIdbgLpthDThn31FJfR7nzODJdcvbMCxbSyxyZu8f0k-7Ut94INkdE3N0Bw3_exYk0LIUwALPuC/s1600/API+App.png"
data-original-width="512" data-original-height="512"
style="margin-left:10px;margin-top:-13px;width:40px" /><br />
<span style="background-color:yellow">Warning:</span>
<br>
As written several time before, it seems that <span style="background-color:yellow">this category has been
kept
only for marketing reason</span>. It seems that there is only Web App category left from now in the
Portal.
App Service = Web App.
<br>Anyway I post here a way to create Api Apps. I tried and didn't receive a message saying they are
deprecated
(as I received for Mobile Apps)
<br>
<br>
Microsoft information:
<br>
<div style="border:solid 1px silver;padding:3px;">
Create and deploy RESTful APIs in seconds, as powerful as you need them
<br />
Leverage your existing tools to create and deploy RESTful APIs without the hassle of managing
infrastructure. Microsoft Azure App Service API Apps offers secure and flexible development, deployment,
and
scaling options for any sized RESTful API application. Use frameworks and templates to create RESTful
APIs
in seconds. Choose from source control options like TFS, GitHub, and BitBucket. Use any tool or OS to
develop your RESTful API with .NET, Java, PHP, Node.js or Python.<br />
<br />
<ul>
<li>Fastest way to build for the cloud</li>
<li>Provision and deploy fast</li>
<li>Simple access control and authentication</li>
<li>Secure platform that scales automatically</li>
<li>Great experience for Visual Studio developers with automatic SDK generation</li>
<li>Open and flexible for everyone</li>
<li>Monitor, alert, and auto scale (preview)</li>
</ul>
source : Azure Portal Description when attempting to create<br />
<br />
Useful links:
<br>
<a href="https://azure.microsoft.com/en-in/services/app-service/api/">Link to Microsoft Azure API App
Service Portal</a><br />
<a
href="https://azure.microsoft.com/en-in/resources/videos/connect-2015-what-s-new-in-app-service-api-apps/">Link
to the old API App Service Video (11-18-2015) not updated</a><br />
</div>
<br />
<b>Creation of an API App</b>
<br />
<br />
The only way to create Api Apps today (september 2019) is to use the + Create a resource and make a search.
The
API App has been hidden from the web category. Thus they have not been deprecated but might be soon I think.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw82pjk64rfMG5AfMmh0uqGzOrXq-KmFkdfqxIkrhYIPz-XKsTHigEbz8aPLB-SPfZLacAc8n-ZuMUDJvhyakJ7Xq9QhyphenhyphenOiO-LUxq6UN4oxcPpNi9JHxivLQ9RhnesB25cycJNTPU_uf06/s1600/quick-tutorial-nodejs-app-service-azure+-+02+-+old+app+services+classification+-+Web+App+Api+App.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw82pjk64rfMG5AfMmh0uqGzOrXq-KmFkdfqxIkrhYIPz-XKsTHigEbz8aPLB-SPfZLacAc8n-ZuMUDJvhyakJ7Xq9QhyphenhyphenOiO-LUxq6UN4oxcPpNi9JHxivLQ9RhnesB25cycJNTPU_uf06/s1600/quick-tutorial-nodejs-app-service-azure+-+02+-+old+app+services+classification+-+Web+App+Api+App.png"
style="width:100%" /></a>
<br>
<br />
Then, click on the API APP button to access to the creation blade. No deprecation message for the
moment.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMeCQRf8EIm6FuoB-3S-aMPdyqlHoQUL6_p9mHaswG4rxwwBZix2cLjyTGV__XCnm4267iNkUlc6Z_ObZBCiF_9Y-3YIybKekY71k5xkEytYO6pBr-__rMCDTY3Rnf8eFgfR5OuQ5-E9lT/s1600/Azure-App-Service+-+12+-+API+App+creation.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMeCQRf8EIm6FuoB-3S-aMPdyqlHoQUL6_p9mHaswG4rxwwBZix2cLjyTGV__XCnm4267iNkUlc6Z_ObZBCiF_9Y-3YIybKekY71k5xkEytYO6pBr-__rMCDTY3Rnf8eFgfR5OuQ5-E9lT/s1600/Azure-App-Service+-+12+-+API+App+creation.png"
style="width:100%" /></a>
<br />
<br>
you can plug your App on an existing (free) service plan, useful!
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4mesM0KZw40WI_yn6lIxgBjQM57kd5ht4ediWpcLzGTktK84pD1QUH0daoDmVu3wZvCBPRC5XsonGPdkqc5wowPl9X1aAqsAtpL_5Vzr9h7uI4IivG4RnS2mBzISXP_4czQZ2qiMWdR5X/s1600/Azure-App-Service+-+13+-+API+App+creation.png.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4mesM0KZw40WI_yn6lIxgBjQM57kd5ht4ediWpcLzGTktK84pD1QUH0daoDmVu3wZvCBPRC5XsonGPdkqc5wowPl9X1aAqsAtpL_5Vzr9h7uI4IivG4RnS2mBzISXP_4czQZ2qiMWdR5X/s1600/Azure-App-Service+-+13+-+API+App+creation.png.png"
style="width:100%" /></a>
<br>
<br>
You can notice that the API Apps kept their icons.
<br>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaXNEX36g_Tg3idxMLWJcuVK5UaKpIKYs5kNC6BP_q7EiEAcKacAQVGIHOEnpyHDSp9OfZ2bI22O_-uaVb6ydRCVK6eQz9cGvUFhckCwUR1Q-vC-MMfWRi2e47qPk8RKeab1beJGrXxzRK/s1600/Azure-App-Service+-+14+-+API+App+created.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaXNEX36g_Tg3idxMLWJcuVK5UaKpIKYs5kNC6BP_q7EiEAcKacAQVGIHOEnpyHDSp9OfZ2bI22O_-uaVb6ydRCVK6eQz9cGvUFhckCwUR1Q-vC-MMfWRi2e47qPk8RKeab1beJGrXxzRK/s1600/Azure-App-Service+-+14+-+API+App+created.png"
style="width:100%" /></a>
<br>
<br>
I checked a little bit and for the moment, <span style="background-color:yellow">no difference with a Web
App
found, excepted the icon. </span>
<br>
<br>
<span style="color:red">I didn't update this last part because serverless apps seems to be outside of the
real
App Service scope from mid 2018.</span>
<br>Even if, when creating a Function, it appears in the App Service section of the portal.
<h2>Serveless App</h2>
<!--Logic Apps -->
<h3>Logic App</h3>
<img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2IzqFVCjiuGfPURkaLEPd0WgBcFn5XwgrTo4Pdrsm6pCFqH1ZJYO9XIWJN4oex7nsDl5cgCdHCiJIbu7ZqCIj-pLSIHHSQKXiRDPP7kMhItZylGLoP1G-KFujPvI2uMfQq4QIjNLD7o5V/s1600/logic+app.png"
style="margin-left:13px;margin-top:-10px;width:40px" />
<br />
<br />
Logic Apps allow developers to design workflows that articulate intent via a trigger and series of steps,
each
invoking an App Service API app whilst securely taking care of authentication and best practices like
durable
execution.<br />
Easy to use design tools - Logic Apps can be designed end-to-end in the browser. Start with a trigger - from
a
simple schedule to whenever a tweet appears about your company. Then orchestrate any number of actions using
the
rich gallery of connectors.<br />
<br />
Compose SaaS easily - Even composition tasks that are easy to describe are difficult to implement in code.
Logic
Apps make it a cinch to connect disparate systems. Want to create a task in CRM based on activity on your
Facebook or Twitter accounts? Want to connect your cloud marketing solution to your on-premises billing
system?
Logic apps are the fastest, most reliable way to deliver solutions to these problems.<br />
<br />
Extensibility baked in - Don't see the connector you need? Logic Apps are part of the App Service suite and
designed to work with API apps; you can easily create your own API app to use as a connector. Build a new
app
just for you, or share and monetize in the marketplace.<br />
<br />
Real integration horsepower - Start easy and grow as you need. Logic Apps can easily leverage the power of
BizTalk, Microsoft's industry leading integration solution to enable integration professionals to build the
solutions they need.<br />
<br />
source : Azure Portal Description when attempting to create<br />
<br />
Creation: <br />
<br />
On Azure Portal Click on App Service, then on Add: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZFjQ7Bz5g5w8Q8XxSprfyZR6NESYLW0BPjeaTu2nv08DYmEcW38dYVCeULJhxJsd5TyCpGv_wksYxQXx6Z30peNSJVqwKmhIQ09xEz_Y9YUtDX2EWM8dmXSIJLo6v14qXNHktzPlKgtNP/s1600/App+Service+-+01+App+service+creation.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZFjQ7Bz5g5w8Q8XxSprfyZR6NESYLW0BPjeaTu2nv08DYmEcW38dYVCeULJhxJsd5TyCpGv_wksYxQXx6Z30peNSJVqwKmhIQ09xEz_Y9YUtDX2EWM8dmXSIJLo6v14qXNHktzPlKgtNP/s640/App+Service+-+01+App+service+creation.png"
class="screenshot-large" /></a><br />
<br />
Then, scroll down to display the Logic App Section, and on the "More" link to display all the options
regarding
Logic Apps:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Hga0CMXfRVUdrW6pfAtZvm3mNPyJ0Lh-MDOFvaD6Ye_dAs3EkNhCUmo2V7d8Mc2yA4rN7o6NZcHW32LLtKnzmzOB6f9LIezNbHP1es88wMErcCxEe-PAaNDFRv7gCFt7HIyTNzNLgma5/s1600/App+Service+-+05+Logic+App++creation.png"
imageanchor="1"><img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Hga0CMXfRVUdrW6pfAtZvm3mNPyJ0Lh-MDOFvaD6Ye_dAs3EkNhCUmo2V7d8Mc2yA4rN7o6NZcHW32LLtKnzmzOB6f9LIezNbHP1es88wMErcCxEe-PAaNDFRv7gCFt7HIyTNzNLgma5/s640/App+Service+-+05+Logic+App++creation.png"
class="screenshot-large" /></a><br />
<br />
<br />
<!--Function -->
<h3>Function</h3>
<img border="0"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBdYfEIICPcs_rveD_Ed-B1-wNgF2ce-nPK1HzbhM1UCcpHtDTaZ1XuWHFXJqcGAnB52yjv69hh_M1p4en-8Bl5LteDG5BjdP-3t8kJqjyedkEJ8LiyLp-b9XGfkng3tbF3-ySKWeRiCIc/s1600/Azure+App+Service+Function+icon.png"
style="margin-left:13px;margin-top:-10px;width:40px" />
<br />
Write any function in minutes – whether to run a simple job that cleans up a database or build a more
complex
architecture. Creating functions is easier than ever before, whatever your chosen OS, platform, or
development
method.
<br />
source : Azure Portal Description when attempting to create<br />
<br>
<br>
<div class="videoWrapper">
<iframe src="https://channel9.msdn.com/Blogs/Azure/Azure-Functions-overview/player"
style="width:100%;Height:100%" allowFullScreen frameBorder="0"></iframe>
</div>
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-26726936484217948452016-05-31T16:32:00.001+02:002019-09-05T22:10:12.968+02:00Improve SharePoint 2013 search relevance<div class="h2-paragraph">
You want to ensure that the search results that are returned to the user match what the user wanted to find and that the results that are returned on the first page are the most relevant, so the user does not have to look through several pages of results to find the best matches for their search ? <br />
<br />
<b>This is called Search Relevancy! </b><br />
<br />
In this post we are going to learn how to customize SharePoint 2013 search relevance. We will see how to create and deploy custom ranking models and how to test them. <br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi832oBmC0WsiTn4cySEH928jshmaOdWpxosUl1rtC0Kw9Uk0rdNxWG2utlK_fkHCf8Wzp6MhMfipWF2eXJLhQ2yVP5NPGc3gwZ-crCChjBID6QAYI5MTIrdUNq9_pSTVgxarR0mFMsVV8l/s1600/ranking+model+-+15+-+test+custom+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi832oBmC0WsiTn4cySEH928jshmaOdWpxosUl1rtC0Kw9Uk0rdNxWG2utlK_fkHCf8Wzp6MhMfipWF2eXJLhQ2yVP5NPGc3gwZ-crCChjBID6QAYI5MTIrdUNq9_pSTVgxarR0mFMsVV8l/s1600/ranking+model+-+15+-+test+custom+ranking+model.png" class="screenshot-standard" /></a><br />
<div style="clear:both"></div><br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">1 - What you need to do this tutorial</div>You need: <br />
<ul><li>A SharePoint 2013 Enterprise on premise environment</li>
<li>Visual Studio 2013 installed on this environment</li>
</ul><br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">2 - Definition</div>The ranking model is an XML file that SharePoint uses to assign a rank for each search result . The display of results is made according to this rank. To adjust the relevance of research in SharePoint 2013 you thus need to write a custom ranking model and deploy it so that it takes into account the preferences of the user in matter of display of results .<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">3 - Start your ranking model customization based on a SharePoint ranking model template</div><br />
<br />
To get the default ranking model template, log on any server in the SharePoint 2013 server farm with Administrator rights.<br />
Create a directory, for example c: \ rankModel<br />
Open a Powershell for SharePoint command prompt and enter the following lines:<br />
<br />
</div>
<div style="font-family:courrier"><pre class="code-standard">$ssa = Get-SPEnterpriseSearchServiceApplication
$owner = Get-SPenterpriseSearchOwner -Level ssa
$defaultRankingModel = Get-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner | Where-Object { $_.IsDefault -eq $True }
$twoLinearStagesRankingModel.RankingModelXML > c:\rankmodel\defaultRankingModel.xml
</pre></div>
<div class="h2-paragraph">
Note: Microsoft recommends to use a two linear ranking model (it is a different and newer xml structure). To use it, you have, at least, to update your SharePoint Farm with the SharePoint Server 2013 cumulative update that was published in March 2014.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj19N7EIz6QNIstetcCf04TppywvhNajnQtaJ0xCU1Vztb5gIY-_FLFgJFywWMewF3fu0rlKVw3W5-IPRRvcSGfCrjuLi8PPgWjWfD79ECXgPTySM7FwYP_6tC7ZbjlbJmQ8owlXBqy1-m8/s1600/ranking+model+-+10+-+get+default+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj19N7EIz6QNIstetcCf04TppywvhNajnQtaJ0xCU1Vztb5gIY-_FLFgJFywWMewF3fu0rlKVw3W5-IPRRvcSGfCrjuLi8PPgWjWfD79ECXgPTySM7FwYP_6tC7ZbjlbJmQ8owlXBqy1-m8/s1600/ranking+model+-+10+-+get+default+ranking+model.png" class="screenshot-standard"/></a><br />
<br />
After having executed the previous SherPoint Powershell instructions, you will see appear the requested ranking model as an xml file in the c:\rankmodel folder.<br />
Then, open the defaultRankingModel.xml, xml file into a text editor. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg_tMWpaMi-mAYTdgWYxQq-PzTf1ahm5kIcsGkEPSTq-epSQkuOPMaUesC52PRROIYkJq4dn9bTKE0y9FZd1Exv_HP93TDXlIHbn67VYclBtqI9Pz9ML-A4mYzkBoJTTPJdJP1-t645Pc3/s1600/ranking+model+-+11+-+get+default+ranking+model.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg_tMWpaMi-mAYTdgWYxQq-PzTf1ahm5kIcsGkEPSTq-epSQkuOPMaUesC52PRROIYkJq4dn9bTKE0y9FZd1Exv_HP93TDXlIHbn67VYclBtqI9Pz9ML-A4mYzkBoJTTPJdJP1-t645Pc3/s1600/ranking+model+-+11+-+get+default+ranking+model.png" /></a>
<br />
Note that the ranking model template is identified by an unique GUID.<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">4 - Test the ranking model template (first tool)</div>I developed a tool, the SPsearchRankingModelTester that can test the relevance of the search results according to a given ranking model (<a href="http://johanolivier.blogspot.fr/2011/05/improve-sharepoint-search-relevance.html">Thanks to Johan Olivier</a>).<br />
It is a console application.<br />
This tool allows to easily test an application after having deployed a custom ranking model <span style="background-color:yellow"> without having to register each time the new rankig model in search results web part which is tedious for testing.</span><br />
You can find the <span style="color:red">package ready to use in CodePlex</span>: <a href="https://sp2013searchrankingmodeltester.codeplex.com/releases/view/621504">SPSearchRankingModelTester-package </a>.<br />
You can find the source code of this application in <a href="https://sp2013searchrankingmodeltester.codeplex.com/">the codePlex project</a>, or in my GitHub repositery: <a href="https://github.com/MarcCharmois/SP2013searchRankingModelTester">SP2013searchRankingModelTester</a><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">4.1 Deploying SP2013searchRankingModelTester</span><br />
<br />
Copy the downloaded package on a server of the SharePoint 2013 Farm, unzip it. <br />
Modify the exe.config file: change the "value" attribute of the SPsiteAddress key and use the site collection where you want to test the search with a specific ranking model. For exemple, you can use the Url of a your SharePoint 2013 search center.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">4.2 Using the SP2013searchRankingModelTester</span><br />
<br />
Double click the .exe file. <br />
The console application is opening and displaying your site collection Url (the one referenced in the exe.config file).<br />
You are then, prompted for a request. Type your request. <br />
Then, you are prompted for the GUID of your ranking model. <br />
<br />
Make a right-click on the top of the window to paste the GUID you have previously copied from the xml file: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUQ-iD7ntPYMazVd2nMV6L8RxaoJeSgFxSdYnFJIjg_NTav1mahGQ9r9D2INJ-G3KU_pPGnBrOt2_ew_PLpfbe9l3cz1Cl5KPdGJcLyt-GhiFiQKcT-8aCoAVynMw97L7hwHdCaG2Xdp4K/s1600/ranking+model+-+12+-+test+default+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUQ-iD7ntPYMazVd2nMV6L8RxaoJeSgFxSdYnFJIjg_NTav1mahGQ9r9D2INJ-G3KU_pPGnBrOt2_ew_PLpfbe9l3cz1Cl5KPdGJcLyt-GhiFiQKcT-8aCoAVynMw97L7hwHdCaG2Xdp4K/s1600/ranking+model+-+12+-+test+default+ranking+model.png" class="screenshot-standard" /></a><br />
<br />
In the next screen shot, I use the GUID of the SharePoint 2013 default ranking model. <br />
Once the ranking model GUID typed and the "enter" key pressed, the console application displays the 50th first relevant results according to the ranking model you specified. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6XdQfyVLcUIUsoY1rsyTxpDV7AZqxYGdSqiyFC-L7j-qUvzCrGxj0OPXUA6wr8vCOvpYprgLW3Rl3ahgShW68HwJiMR7vxhkU0qytUs43JnzW75Cy90H3fYigaj_g8Ge30Mi8jWYtcm-Y/s1600/ranking+model+-+13+-+test+default+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6XdQfyVLcUIUsoY1rsyTxpDV7AZqxYGdSqiyFC-L7j-qUvzCrGxj0OPXUA6wr8vCOvpYprgLW3Rl3ahgShW68HwJiMR7vxhkU0qytUs43JnzW75Cy90H3fYigaj_g8Ge30Mi8jWYtcm-Y/s1600/ranking+model+-+13+-+test+default+ranking+model.png" class="screenshot-standard" /></a><br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">5 - Tune your ranking model with rank features</div><br />
There is several ways to customize a ranking model. The xml syntax and the ways to focus on a special point for relevance is not easy to understand. You can refer first to the <a href="">official Microsoft documentation</a>. I am first giving a quick overview of it, then <span style="background-color:yellow">I will explain how to test your changes with several tools.</span><br />
<br />
Roughly you can act on: <br />
<ul><li><b>BM25 rank feature ranks items</b><br />
You specify a property like "body" (the content of the crawled or indexed item) or "Title" (the title of the crawled or indexed item) and give that property a weight in order the relevance to more or less take into account this property. <br />
You can also specify the document length normalization for each property: a title is usually composed with few words although the body is rather long and the query is also usually composed with a few words. So you can tell your ranking model that a single occurence of one of the keywords of the query in the body has the same importance than a single occurence of one of the keywords of the query in the title<br />
<br />
</li>
<li><b>Weight groups</b><br />
You tune this in the Advanced Search Settings, using the search schema feature in the Search service application.<br />
For example, you create a new managed property of the type string that contains about ten words or less. You consider this new managed property to be about as important as the existing managed property Title. In that case, you should map the new managed property to context 1.<br />
Another example. You create a managed property of the type string that contains lots of words, for example a description of something. You should map this new managed property to context 7 because it is similar to the managed property Body, both in length as well as in importance.<br />
<br />
</li>
<li><b>static rank feature ranks items</b><br />
The static rank feature ranks items based on numeric managed properties that are stored in the search index. The numeric managed properties used for relevance rank calculation in static rank features must be of type Integer and set to Refinable or Sortable in the search schema. You can’t use multivalued managed properties in combination with the static rank feature.<br />
For example, UrlDepth is a typical static rank: the less url to reach the result is long, the more that result is relevant. <br />
Another example: you can make your content to be rated by users and make a static rank with this rating.<br />
<br />
</li>
<li><b>Bucketed static</b><br />
The bucketed static rank feature ranks documents based on their file type and language. You can tell your model that a .pdf in english is more relevant than a .docx in french. <br />
<br />
</li>
<li><b>Proximity rank feature</b><br />
The proximity rank feature ranks items depending on the distance between query terms inside the full-text index. The rank score is boosted if two query terms appear in the same managed properties within the full-text index. Proximity calculations are expensive in terms of disk activity and CPU consumption; as a result, proximity boost is carried out only during the second stage of the default SharePoint Server 2013 rank model (if available).<br />
<br />
</li>
<li><b>The dynamic rank feature</b> <br />
It seems to use this if you want to boost a specific property: <br />
The dynamic rank feature ranks an item depending on whether the query property matches a given managed property. If there is a match, the item’s rank score is multiplied with a specific value to distinguish that particular item. The weight attribute is used to control how much this feature affects the overall rank score.<br />
Note<br />
The dynamic rank feature is not customizable; it’s for internal use only. However, if you install the SharePoint Server 2013 cumulative update of August 2013, the AnchortextComplete rank feature is a customizable dynamic rank feature that is part of the default ranking model.<br />
<br />
</li>
<li><b>Freshness</b><br />
The default SharePoint 2013 ranking model doesn’t boost the rank of search results based on their freshness. You can achieve this by adding a new static rank feature that combines information from the LastModifiedTime managed property with the DateTimeUtcNow query property, using the freshness transform function. The freshness transform function is the only transform that you can use for this freshness rank feature, because it converts the age of the item from an internal representation into days.<br />
<br />
</li>
</ul><br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">6 - Testing a custom ranking model</div><br />
<span style="color: #e9ab17; margin-left: 50px;">6.1 Description of the custom ranking model</span><br />
<br />
In the Microsoft documentation, you will find two samples of customized ranking model. Let's show how to deploy and test the second one. <br />
<br />
This ranking model with one linear stage contains these four rank features:<br />
<ul><li>BM25 This rank feature is based on managed properties Title and body; the w attribute for title is set so that hits of query terms in Title are two times (2x) more important than hits of query terms in body.<br />
<br />
</li>
<li>UrlDepth This rank feature is based on the UrlDepth managed property, which is available by default in SharePoint installations. UrlDepth contains the number of backslashes (\) in the URL of a document. The inverse rational (InvRational) transform ensures that documents with shorter URLs receive higher rank scores.<br />
<br />
</li>
<li>TitleProximity This rank feature boosts documents if some of the query terms occur close to each other in the title of these documents.<br />
InternalFileType This rank feature boosts documents of type HTML, DOC, XLS, or PPT. The names of the buckets in the definition of the rank model are provided for readability only.<br />
</li>
</ul>
<pre class="code-standard"><?xml version="1.0"?>
<rankingmodel2stage name=" RankModel2"
description="Rank model -- example 2"
id="DE48A3A1-67CE-44A2-9712-E8A5128787CF"
xmlns="urn:Microsoft.Search.Ranking.Model.2NN">
<rankingmodel2nn id="A0A030D1-805D-437E-A001-CC151ED7473A" precalcEnabled="0">
<hiddennodes count="1">
<thresholds>
<threshold>0</Threshold>
</Thresholds>
<layer2weights>
<weight>1</Weight>
</Layer2Weights>
</HiddenNodes>
<rankingfeatures>
<bm25main name="BM25" k1="1">
<layer1weights>
<weight>1</Weight>
</Layer1Weights>
<properties>
<property name="Title" propertyName="Title" w="2" b="0.5" />
<property name="body" propertyName="body" w="1" b="0.5" />
</Properties>
</BM25Main>
<static name="UrlDepth" propertyName="UrlDepth" default="1">
<transform type="InvRational" k="1.5"/>
<layer1weights>
<weight>0.5</Weight>
</Layer1Weights>
</Static>
<minspan name="TitleProximity" propertyName="Title" default="0" maxMinSpan="1" isExact="0" isDiscounted="0">
<normalize SDev="1" Mean="0"/>
<transform type="Linear" a="1" b="-0.5" maxx="2"/>
<layer1weights>
<weight>1.2</Weight>
</Layer1Weights>
</MinSpan>
<bucketedstatic name="InternalFileType" propertyName="InternalFileType" default="0">
<bucket name="http" value="0">
<hiddennodesadds>
<add>1.5</Add>
</HiddenNodesAdds>
</Bucket>
<bucket name="doc" value="1">
<hiddennodesadds>
<add>2.5</Add>
</HiddenNodesAdds>
</Bucket>
<bucket name="ppt" value="2">
<hiddennodesadds>
<add>0.5</Add>
</HiddenNodesAdds>
</Bucket>
<bucket name="xls" value="3">
<hiddennodesadds>
<add>-3.5</Add>
</HiddenNodesAdds>
</Bucket>
</BucketedStatic>
</RankingFeatures>
</RankingModel2NN>
</RankingModel2Stage>
</pre><br />
<span style="color: #e9ab17; margin-left: 50px;">6.2 Custom ranking model deployment</span><br />
<br />
Copy the previous xml in a file and name this file RankingModel2.xml. Copy this file in the previous folder c:\rankmodel. <br />
Then, execute the following Powershell for SharePoint instructions: <br />
<br />
$myRankingModel = Get-Content c:\rankmodel\ RankingModel2.xml<br />
$myRankingModel = [String]$myRankingModel<br />
$ssa = Get-SPEnterpriseSearchServiceApplication<br />
$owner = Get-SPenterpriseSearchOwner -Level ssa<br />
$newrm = New-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -RankingModelXML $myRankingModel<br />
<br />
Here is the screenshot for control: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgssmferOs8ztkrPdM8kfbnu89RKGyBWTf0lL51BYWSb6d11KvYo52SBD-K86LGt-fz7lgFoaRNg5wz5jTVXU1UJLG8iU3sy0sQbKbunPNSieymsAQgDnm9ENxwb2a2BTArsH3ubXzS6FXH/s1600/ranking+model+-+14+-+deploy+custom+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgssmferOs8ztkrPdM8kfbnu89RKGyBWTf0lL51BYWSb6d11KvYo52SBD-K86LGt-fz7lgFoaRNg5wz5jTVXU1UJLG8iU3sy0sQbKbunPNSieymsAQgDnm9ENxwb2a2BTArsH3ubXzS6FXH/s1600/ranking+model+-+14+-+deploy+custom+ranking+model.png" class="screenshot-standard" /></a><br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">6.3 testing the custom ranking model</span><br />
<br />
To test the custom ranking model, we just have to use the previous tool. So double click on the .exe and this time after having typed the query, type the GUID of the custom ranking model:<br />
<br />
DE48A3A1-67CE-44A2-9712-E8A5128787CF<br />
<br />
You will see that the results are sorted in a completely different way accorded to the new and custom ranking model: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM7_i1EZrJv6nqhbfQEoAi36xfuppUs6E14OsrbEQYQvQkqbHPWtgwulFFvkK905jHwnQjycvFCqAfEtHXJLksHV2OshavZg5B3GzJpgw2QtCTYREMWu5EBN7RJSxkAi8nvIfQwib5hVi2/s1600/ranking+model+-+15+-+test+custom+ranking+model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM7_i1EZrJv6nqhbfQEoAi36xfuppUs6E14OsrbEQYQvQkqbHPWtgwulFFvkK905jHwnQjycvFCqAfEtHXJLksHV2OshavZg5B3GzJpgw2QtCTYREMWu5EBN7RJSxkAi8nvIfQwib5hVi2/s1600/ranking+model+-+15+-+test+custom+ranking+model.png" class="screenshot-standard" /></a><br />
<br />
As I wrote before, understanding the syntax of the ranking model is a difficult work to achieve. By being able to test quickly the modifications of a custom ranking model you can improve your knowledge of the syntax, rules, formula and so on. <br />
<br />
We are going to see more tools to do this...<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">7 - More tools to learn how to customize a SharePoint 2013 search ranking model</div><br />
<span style="color: #e9ab17; margin-left: 50px;">7.1 Tools overview and prerequisites</span><br />
<br />
The two tools that we are going to demonstrate are Add-Ins for SharePoint ( formerly called Apps) .<br />
I will not deny that the requirements to use these tools are difficult to carry out even for a SharePoint developer.<br />
It takes a very good knowledge of SharePoint administration to use these tools because:<br />
<ul><li>The Apps Settings for a SharePoint environment is difficult (especially on a local environment because of, for example, the creation the subdomain) and does not always work at the first time. You have sometimes to delete the service and recreate it for making it work.</li>
<li>One of these tools requires at least ( without it being mentioned in its documentation!), the activation of the User Profile Service Application that requires a lot of expertise ( especially for a local SharePoint 2013 environment)</li>
</ul>However, here is a demonstration of tools and assets that can be drawn.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">7.2 Mavention Explain Rank</span><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Overview</span><br />
SharePoint 2013 has the ExplainRank.aspx page which is a truly hidden gem, that displays the rankdetail for a single item in a more comprehensible way. However, this page is not working! (<a href="https://blog.mastykarz.nl/understanding-item-ranking-sharepoint-2013-search/">see Waldek Mastykarz's post on the subject</a>. <br />
Fortunately, there is a similar and free(!) tool (a SharePoint Add-In) that allows you to do the same.<br />
This Add-In allows to query and for each result to understand the different values ​​assigned by the ranking model and explains its place in the ordering of results.<br />
This is very educational when we want to understand how the ranking model is working.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Installation</span><br />
Log in as Administrator on the research center of the SharePoint environment. Use the upper left menu to add the Add-In (app)<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMcprmwzt7SF4GqTl8qHUHZqP_4mGmB3bgOiTzJNhC4kv31HQ9MRnnHBwRPYRIPlejOi-zI7Ub-6Jtj9JpWXspqKEDtnp8KpkTSKwtZy__0eI5TsWLgRNgUtnhxIosgXvcJ5tlCljxn0Sz/s1600/ranking+model+-+19+-+add+an+app.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMcprmwzt7SF4GqTl8qHUHZqP_4mGmB3bgOiTzJNhC4kv31HQ9MRnnHBwRPYRIPlejOi-zI7Ub-6Jtj9JpWXspqKEDtnp8KpkTSKwtZy__0eI5TsWLgRNgUtnhxIosgXvcJ5tlCljxn0Sz/s1600/ranking+model+-+19+-+add+an+app.png" class="screenshot-medium" /></a><br />
<br />
<br />
In the "Apps" search box enter the name of the publisher " Mavention " to display the catalog.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFSFtDQ1Nr0eDCwEn7BQglkOUk8mcvNl1iuNTM2BxtR6lQC3vBucUpogzpprzlcONF8jjg4rfCGrzGX2jJH6q90T16cIbk0Q6ZJj6R9xgSLvHhqvL6ItN2zgpaNG3AjBB2ho843wLcl2Dk/s1600/ranking+model+-50+-+mavention-sharepoint+store.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFSFtDQ1Nr0eDCwEn7BQglkOUk8mcvNl1iuNTM2BxtR6lQC3vBucUpogzpprzlcONF8jjg4rfCGrzGX2jJH6q90T16cIbk0Q6ZJj6R9xgSLvHhqvL6ItN2zgpaNG3AjBB2ho843wLcl2Dk/s1600/ranking+model+-50+-+mavention-sharepoint+store.png" class="screenshot-standard" /></a><br />
<br />
Locate « Explain Rank » Add-In. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVFOg9VBEiiOgQm48oCEFHHodUKfderylgz0ko7Cou02o3w2pKhfIv4ToSkHZMvmj_msTz6cmusG8kkmWRI5X1BmG_iqbpF-ERppymDXeAXDucSIN8kMzidwL68qp5xI_Su8BlFUfCOz-M/s1600/ranking+model+-50+-+mavention-sharepoint+store02.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVFOg9VBEiiOgQm48oCEFHHodUKfderylgz0ko7Cou02o3w2pKhfIv4ToSkHZMvmj_msTz6cmusG8kkmWRI5X1BmG_iqbpF-ERppymDXeAXDucSIN8kMzidwL68qp5xI_Su8BlFUfCOz-M/s1600/ranking+model+-50+-+mavention-sharepoint+store02.png" class="screenshot-standard" /></a><br />
<br />
Click the Add-In to deploy it and give it the appropriate permissions.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixfzKX32ssN-N21meZj_BZuqUJLYqvc2K4msIpkDCo0eSE7WIZo5fcmYiC1JYr9GwSpOZ7klNMF_cEcpddTCdWUEv5EXAgi-AZT29HzFjljCyn4TJfvnd4iAFWhzW_E9ynoWFO2GefhtlA/s1600/ranking+model+-51+-+mavention-sharepoint+store03.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixfzKX32ssN-N21meZj_BZuqUJLYqvc2K4msIpkDCo0eSE7WIZo5fcmYiC1JYr9GwSpOZ7klNMF_cEcpddTCdWUEv5EXAgi-AZT29HzFjljCyn4TJfvnd4iAFWhzW_E9ynoWFO2GefhtlA/s1600/ranking+model+-51+-+mavention-sharepoint+store03.png" class="screenshot-standard" /></a><br />
<br />
Once deployed, the add-in appears in usable the Add-In ( Apps) and can be used .<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAEnZJccbvgJzChpFhaCLQsBYFwsa_gORpjnss6kGYcKvne9pWpGEEeZtrzYgIpgT7Xmqp07PoGTdxqkRuDLAifckuLnZnPxxvX2pPmIanub8RJctdlOs-8VPeMrNzHsvb66wj36ZM40ag/s1600/ranking+model+-52+-+mavention-sharepoint+store04.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAEnZJccbvgJzChpFhaCLQsBYFwsa_gORpjnss6kGYcKvne9pWpGEEeZtrzYgIpgT7Xmqp07PoGTdxqkRuDLAifckuLnZnPxxvX2pPmIanub8RJctdlOs-8VPeMrNzHsvb66wj36ZM40ag/s1600/ranking+model+-52+-+mavention-sharepoint+store04.png" class="screenshot-standard" /></a><br />
<br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Using the "Explain Rank" Mavention Add-In</span><br />
<br />
Open the Add- In home page and enter a query.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0-uGkJdi9WOMbX9ATqt24xf80b-ohO3H2Adx9CrbzaEs4YV7tWvh-7-D28QCQxnkfCd0s6ctbGK0VOUsCMXPXexK0NjRCQPdAhrNB1CEr_Sgaavc99eZfqOPkPVokzG2cgbyNWTpIrfEv/s1600/ranking+model+-53+-+mavention-using.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0-uGkJdi9WOMbX9ATqt24xf80b-ohO3H2Adx9CrbzaEs4YV7tWvh-7-D28QCQxnkfCd0s6ctbGK0VOUsCMXPXexK0NjRCQPdAhrNB1CEr_Sgaavc99eZfqOPkPVokzG2cgbyNWTpIrfEv/s1600/ranking+model+-53+-+mavention-using.png" class="screenshot-standard" /></a><br />
<br />
Start the query <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBJskwhUNwdOEVabVMmCfRItel3ekysxCVxtQ2u2HURLg1zStz5GTI1Z2ES1gf-TqedRqT2ir_5aIUc41Ljz725y8p5Wzv584eccQPAWZTpHr9CVTRadvBogCSxOFusGYuRVd_TQMqPm2T/s1600/ranking+model+-54+-+mavention-using.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBJskwhUNwdOEVabVMmCfRItel3ekysxCVxtQ2u2HURLg1zStz5GTI1Z2ES1gf-TqedRqT2ir_5aIUc41Ljz725y8p5Wzv584eccQPAWZTpHr9CVTRadvBogCSxOFusGYuRVd_TQMqPm2T/s1600/ranking+model+-54+-+mavention-using.png" class="screenshot-standard" /></a><br />
<br />
Before each result a radio button helps to understand how the ranking model has awarded this rank for this result : what used properties and weight related to the presence of a particular word of the request in a particular property.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi27NMwx35pgzBdVit_TINnZaISxcE6Y29URRuQg2t-C5BKteDzbTs2PmaLwcJKgoFN30XZHdJ8jL0XdeLwKEv0aCJw0uK1t5QV7VIeRoinGEwjAqyJr2TPriTmYOrqNzxSCQNcfnjKv6fA/s1600/ranking+model+-55+-+mavention-results.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi27NMwx35pgzBdVit_TINnZaISxcE6Y29URRuQg2t-C5BKteDzbTs2PmaLwcJKgoFN30XZHdJ8jL0XdeLwKEv0aCJw0uK1t5QV7VIeRoinGEwjAqyJr2TPriTmYOrqNzxSCQNcfnjKv6fA/s1600/ranking+model+-55+-+mavention-results.png" class="screenshot-standard" /></a><br />
<br />
This allows us to better understand how a standard or a custom ranking model is acting in the ordering of results.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">7.3 Ranking Model Tuning</span><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Overview</span><br />
<br />
This Add-in is more difficult to use than the previous one. It helps doing what we have done previously that is to mean "creating a custom ranking model", but in a guided manner , and without having to manipulate the xml.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Installation</span><br />
<br />
Proceed as for the Add-In " Explain Rank " of Mavention , but instead of entering Mavention in the search box, enter the name of the Add-In " Ranking Model Tuning ".<br />
Then install the Add-In .<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp9ILlVvG3HFPWFopB6P66y9M9vf8rmfFJxXHVTi_LVHqWzpO6Jha7f7lueaRZCO3wQCSK8v-3tCjUf4we0DTdEBeE8f7C5bSeIk7BSmqAhshbJ27KbBL9epEcgja8SbpO8R0-o35QMYj0/s1600/ranking+model+-+20+-+ranking+model+tuning+-+Trust+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp9ILlVvG3HFPWFopB6P66y9M9vf8rmfFJxXHVTi_LVHqWzpO6Jha7f7lueaRZCO3wQCSK8v-3tCjUf4we0DTdEBeE8f7C5bSeIk7BSmqAhshbJ27KbBL9epEcgja8SbpO8R0-o35QMYj0/s1600/ranking+model+-+20+-+ranking+model+tuning+-+Trust+App.png" class="screenshot-standard" /></a><br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Using the "Ranking Model Tuning" Add-In</span><br />
<br />
The home page of the Add-In presents different ranking models that can serve as a basis to create a customized one. You just have to copy one to work on it.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge48TMOmSKF2eVhNdaJ53jigVpvb5ml7O0fmmNgeM-VD1GJ7TFyIzkEgSoGwVSYVVkzQqoUZIyu8kIfTSQ03M4dF8iexfBR6oEpqLvXUc3nQnQG9SnzAs0GdOdUo31-zpPHegMG84ehNOE/s1600/ranking+model+-+21+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge48TMOmSKF2eVhNdaJ53jigVpvb5ml7O0fmmNgeM-VD1GJ7TFyIzkEgSoGwVSYVVkzQqoUZIyu8kIfTSQ03M4dF8iexfBR6oEpqLvXUc3nQnQG9SnzAs0GdOdUo31-zpPHegMG84ehNOE/s1600/ranking+model+-+21+-+ranking+model+tuning+-+using.png" class="screenshot-standard" /></a><br />
<br />
Once the copy made we can start customizing the copied ranking model.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwXb_rVe_rpIYsl09vr4_d8hd8XqF6SOnrXcB9Rv076VU4czytXTbzQ23BeUJSy77EGEMocKOEIwjtBR_4955dX8CpUwPtljNmmrsSX2m3IKZWT9s0-dWif2oyLajgSmI-6KFJK4ZFAV5u/s1600/ranking+model+-+23+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwXb_rVe_rpIYsl09vr4_d8hd8XqF6SOnrXcB9Rv076VU4czytXTbzQ23BeUJSy77EGEMocKOEIwjtBR_4955dX8CpUwPtljNmmrsSX2m3IKZWT9s0-dWif2oyLajgSmI-6KFJK4ZFAV5u/s1600/ranking+model+-+23+-+ranking+model+tuning+-+using.png" class="screenshot-standard" /></a><br />
<br />
<br />
There are two macro- features : "Adding a judgment sets " or "Adding a rank features"<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDBH4KA0S6UsEZ1kNwdY55UMX1Csd0QVO6UxxVYqYBaDW5PVKUUIaCGv1vs7pksDPbcdHjrQUFvQtIQrB1r-v4EQzvUUCikzy5JrN1Cw4lx78PD2jWSwR67x3zrtgEKEZ8JOYwxyx_Uq0F/s1600/ranking+model+-+24+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDBH4KA0S6UsEZ1kNwdY55UMX1Csd0QVO6UxxVYqYBaDW5PVKUUIaCGv1vs7pksDPbcdHjrQUFvQtIQrB1r-v4EQzvUUCikzy5JrN1Cw4lx78PD2jWSwR67x3zrtgEKEZ8JOYwxyx_Uq0F/s1600/ranking+model+-+24+-+ranking+model+tuning+-+using.png" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4-OUj4e0aAZzCSeLc1rWaf-z_3ZBBtgM_p-aISkEsm3lrYRPA992laVnfsg9xc7InH4tui4RqwzErs3Y4Z3VjVPMHsi91sun-SbGkQQzIJBwi8fWm5LggVfd6Rm_n97_W_H-V0-rd593y/s1600/ranking+model+-+25+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4-OUj4e0aAZzCSeLc1rWaf-z_3ZBBtgM_p-aISkEsm3lrYRPA992laVnfsg9xc7InH4tui4RqwzErs3Y4Z3VjVPMHsi91sun-SbGkQQzIJBwi8fWm5LggVfd6Rm_n97_W_H-V0-rd593y/s1600/ranking+model+-+25+-+ranking+model+tuning+-+using.png" class="screenshot-standard" /></a><br />
<br />
When you copy an existing ranking model, the new ranking model contains the same rank features and weights as in the base model. You can add more managed properties as additional rank features, remove existing features, or tune the weight of existing features.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_2MqphuFPkNvNw8rPXqkCtJy6kLyIw31yrshd9I9DYw-iAHeWv9hvkaXOiCUU3Xk9UQnZvOFiVTl3SH1hl4CmpyA5xlItuEbgzLoNPNGXMPAaJfnPKvKkv5UD4XcxmsRph9TwpexBuZjM/s1600/ranking+model+-+26+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_2MqphuFPkNvNw8rPXqkCtJy6kLyIw31yrshd9I9DYw-iAHeWv9hvkaXOiCUU3Xk9UQnZvOFiVTl3SH1hl4CmpyA5xlItuEbgzLoNPNGXMPAaJfnPKvKkv5UD4XcxmsRph9TwpexBuZjM/s1600/ranking+model+-+26+-+ranking+model+tuning+-+using.png" class="screenshot-standard" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWxOyZzGeq7F-F9f9XacWeI1Vz5BOc3GaBOUhvAmSnmPSgCRGGds4-FZ2S4a5z6vDyeJtKE9-HdsdU-cTBhaPKpgFtAR0vuXL0w3JJ2suQeTH1x-kbV13MImIYh_Ja2wMKGw97UNXzqqa6/s1600/ranking+model+-+27+-+ranking+model+tuning+-+using.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWxOyZzGeq7F-F9f9XacWeI1Vz5BOc3GaBOUhvAmSnmPSgCRGGds4-FZ2S4a5z6vDyeJtKE9-HdsdU-cTBhaPKpgFtAR0vuXL0w3JJ2suQeTH1x-kbV13MImIYh_Ja2wMKGw97UNXzqqa6/s1600/ranking+model+-+27+-+ranking+model+tuning+-+using.png" class="screenshot-standard" /></a><br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Conclusion</span><br />
<br />
This tool helps improve understanding of the xml of a ranking model since he automatically generates the xml based on instructions given by the Add-In UI. Then simply retrieving the new ranking model in xml format to understand how to transform the rules in a well formatted and consistent ranking model xml.<br />
At best, the tool may be suitable for customisations needs of a ranking model without any need to work on the xml.<br />
These various tools and practices can be used to define several approaches to constitute the ranking model appropriate for your needs, although it seems to require a large amount of time for testing and researching to achieve real expertise and mastery of the subject.<br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">Aknowledgements</span><br />
<ul><li><a href="http://johanolivier.blogspot.fr/2011/05/improve-sharepoint-search-relevance.html" >Johan Olivier for quite the same post but for SharePoint 2010</a></li>
<li><a href="https://blog.mastykarz.nl/understanding-item-ranking-sharepoint-2013-search-mavention-explain-rank-app-sharepoint/">Waldek Mastykarz for making me knox the "Explain Rank" Mavention Add-In</a></li>
</ul></div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-70081000497545553992015-11-07T04:36:00.002+01:002019-09-05T22:23:15.701+02:00Embed an Office Group Conversation into SharePoint Online using a JavaScript App, CORS, and the Office 365 Unified API <div class="h2-paragraph">
I am very happy to publish a post where I can use the brand new Office 365 unified API to embed a conversation of the brand new Office Group into a SharePoint Online page!<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig7AVPMaPaeq5uqZdlh6P9LAwg3PWqo-SsmeJLTaAf6_BQiFJfSXOLfExWTcnScRV97VYVNzFtYs-4xN7H8tWcprlzoKI8puLq2oBfk51CGZzXV1c-zHDgwM-4f-qKkBK9waa0vggvhtuC/s1600/Creating+an+Office+App+-+Marc+Charmois+-+001+-+Office+Group+Conversation.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig7AVPMaPaeq5uqZdlh6P9LAwg3PWqo-SsmeJLTaAf6_BQiFJfSXOLfExWTcnScRV97VYVNzFtYs-4xN7H8tWcprlzoKI8puLq2oBfk51CGZzXV1c-zHDgwM-4f-qKkBK9waa0vggvhtuC/s1600/Creating+an+Office+App+-+Marc+Charmois+-+001+-+Office+Group+Conversation.png"></a>
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTMf_86UL-qZjDXSobOyREUwomKqtSxKkPiUnmB2zJZpc_h3_WuUDPCjAM4IPYHW_ZpqC__KlOqa-HzmOChHBblt6zGEb-GRxDT7i5ZLq-EmFIe809GCVMSCNd08o0oF3IdNuuPwHSIrv8/s1600/Creating+an+Office+App+-+Marc+Charmois+-+002+-+Office+Group+Conversation+embedded+into+SharePoint+Online.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTMf_86UL-qZjDXSobOyREUwomKqtSxKkPiUnmB2zJZpc_h3_WuUDPCjAM4IPYHW_ZpqC__KlOqa-HzmOChHBblt6zGEb-GRxDT7i5ZLq-EmFIe809GCVMSCNd08o0oF3IdNuuPwHSIrv8/s1600/Creating+an+Office+App+-+Marc+Charmois+-+002+-+Office+Group+Conversation+embedded+into+SharePoint+Online.png"></a>
<div style="clear:both"></div><div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">1 - Architecture</div><span style="background-color:yellow">A SharePoint Online html page sends an Ajax request to the Office 365 Unified API and get the data of the Office Group.</span>(The SharePoint Online site and the Office Group belong of course to the same Office 365 tenant).<br />
It seems simple at first but it wasn't possible since recently. Why? <br />
Because of the different hostheaders of the different part of Office 365, You can check while navigating through Office 365. For example, recently I created an Office 365 environment and first registered as contososoftware. My domain was contososoftware.onmicrosoft.com. Then I had to buy a domain to activate Yammer (You should have a verified domain in Office 365 to have Yammer activated to Enterprise. The "onmicrosoft.com" is not a domain but an Office 365 tenant name or a default domain and cannot be used to activate Yammer Enterprise. So I bought marccharmois.com. <br />
(roughly 14 US$ a year, not a big deal). After that, when I go to<br />
<ul><li>My mail, My calendar, My contacts (people), My Tasks, the Url starts with https://outlook.office.com/owa/?realm=marccharmois.com#path=</li>
<li>NewsFeed, OneDrive, Sites, Delve, Video, the Url starts with https://contososoftware-my.sharepoint.com/</li>
<li>Yammer, the Url starts with https://www.yammer.com/marccharmois.com/</li>
<li>a SharePoint Online site, the Url starts with https://contososoftware.sharepoint.com/</li>
</ul>So if I want to deploy an html page somewhere Online in Office 365 and make an Ajax request to a part that has a different hostheader (for example displaying some of my mails into a SharePoint Online page), it normally doesn't work because crosss domain Ajax requests are forbidden by the browsers. It is worse if my HTML page is deployed on a server.<br />
Cross-origin resource sharing (CORS) is a mechanism that allows that. CORS defines a way in which a browser and server can interact to safely determine whether or not to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests. It is a recommended standard of the W3C. (Wikipedia)<br />
Of course Microsoft sets up Cors within Office 365 in order developers to be allowed to performed Ajax requests without being bothered by the different hostheaders of Office 365.<br />
The CORS of Office 365 is based on Microsoft Azure:<br />
<ul><li>You register an App in Azure and you are provided with ID's that you place in your code.</li>
<li>In the Azure App, you also reference the Urls of the pages that are planned to call the Office 365 API with cross domain requests</li>
</ul>This double registration allows the CORS of Office 365 to properly work and also manage the oauth authentication. <br />
<br />
That leads to the fact that the term "Application" or App has a double meaning. It could be: <br />
<ul><li>The pages that you have deployed somewhere on a server or within the Office 365 cloud (for example SharePoint Online) and that performs the Ajax requests and displays the data. Let's call this the physical part of the App, or the physical App</li>
<li>The Application that you had to add to Azure for getting the Office 365 CORS and the oauth authentication to work. Let's call that the virtual part of the App, or the virtual App</li>
</ul>In the case of this tutorial, my physical App is just an html page added to a SharePoint Online team site using explorer mode (WebDAV protocol)<br />
It is very similar of what I did when <a href="http://mosshowto.blogspot.fr/2015/10/programmatically-embed-yammer.html">I embedded a Yammer conversation within SharePoint Online</a>. This is super convenient because I can program and deploy quickly a physical App in Office 365 based on an html page that uses only Javascript!<br />
It could seem a little bit difficult to understand at this point of the post, but I will explain all the operations to do it step by step with all the detailed screenshots as usual, so don't worry. I also did a diagram that can summarize all this in a clearer way: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJB0XA4fniwEBIOiPqqpiXkyb6tZfMZnUtEojHiHMHGsxV6-HucRxo3BIUc6e7E_7OjdO_Qy_uFjd6z-H53Puh-f-LMcdRuNO8L4gTKWICmSOVw2a0Uq4zr7GB3vaaWVtGRClMiY57eSyF/s1600/JavaScript+App+Schema.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJB0XA4fniwEBIOiPqqpiXkyb6tZfMZnUtEojHiHMHGsxV6-HucRxo3BIUc6e7E_7OjdO_Qy_uFjd6z-H53Puh-f-LMcdRuNO8L4gTKWICmSOVw2a0Uq4zr7GB3vaaWVtGRClMiY57eSyF/s1600/JavaScript+App+Schema.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">2 - What you need to do this tutorial</div>You need: <br />
<ul><li>An Office 365 environment with a global admin access.<br />
If you don't have any, you can subscribe to a trial environment <a href="https://products.office.com/en-us/business/office-365-enterprise-e3-business-software">like this one (the one the which with you can get Yammer but you will have to buy a domain)</a> or better subscribe to <a href="http://dev.office.com/devprogram">the Office 365 dev program to get a ONE YEAR free office 365 tenant!</a></li>
<li>An Azure subscription <br />
If you don't have any, you can create a new Azure subscription but you will be asked for your credit card informations. It won't be charged, don't worry. But simply, if you don't have an Azure subscription and no credit card, you just can't do this tutorial, but you can read how I did anyway. </li>
</ul>Once you can access to an Office 365 environment using a business account with global administrator privileges, the first thing you need to do is register your application with Azure AD.<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;"><br />
3 - Creating the (virtual) App within Microsoft Azure</div><span style="color: #e9ab17; margin-left: 50px;">3.1 Create a new subscription to Microsoft Azure</span><br />
To Navigate to the Azure Portal you can use this link: <a href="https://manage.windowsazure.com/">https://manage.windowsazure.com/</a><br />
you can also access to it within 0ffice 365:<br />
Log on to Office 365. From the Home page, select the Admin icon to open the Office 365 admin center.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvgMOtHNXvd1D2qR1H2CS5gw8yEfhR0Zbu0lpnMQhyphenhyphenFs2HX-N4CH9X-kstSpMnTgVhyphenhyphen9wiQCm_UNARS5m95eDHX1mZ3L4AJ_3iJ6QpCfBUSCk6JOuSvPMYsHPiE9UYsZbFlrH3H3cfkhUf/s1600/Creating+an+Office+App+-+Marc+Charmois+-+005+-+Azure+-+connection.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvgMOtHNXvd1D2qR1H2CS5gw8yEfhR0Zbu0lpnMQhyphenhyphenFs2HX-N4CH9X-kstSpMnTgVhyphenhyphen9wiQCm_UNARS5m95eDHX1mZ3L4AJ_3iJ6QpCfBUSCk6JOuSvPMYsHPiE9UYsZbFlrH3H3cfkhUf/s1600/Creating+an+Office+App+-+Marc+Charmois+-+005+-+Azure+-+connection.png"></a><br />
<br />
In the menu page along the left side of the page, scroll down to Admin and select Azure AD.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz5VF7ZPpwKue4-Pg28PGQrLHxMJdjLYV1M2gG4_s7Ng9yqM1QTSZwPUVLpFrU81rNYdWba6Fkl8raNSqGckDFbgP-Cu1vKuYA0ynz2MbqCVwErs22ysbZv76ceWlRYXX8eL7aJZo0vz_T/s1600/Creating+an+Office+App+-+Marc+Charmois+-+006+-+Azure+-+connection.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz5VF7ZPpwKue4-Pg28PGQrLHxMJdjLYV1M2gG4_s7Ng9yqM1QTSZwPUVLpFrU81rNYdWba6Fkl8raNSqGckDFbgP-Cu1vKuYA0ynz2MbqCVwErs22ysbZv76ceWlRYXX8eL7aJZo0vz_T/s1600/Creating+an+Office+App+-+Marc+Charmois+-+006+-+Azure+-+connection.png"></a><br />
<br />
If prompted, log in using the credentials you created for your O365 subscription.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6JsmdvwuPInSTsaoTwVEW4wOG6RqapHG1jFLwOxj6oOHAkMKFV965Wz4lfA5wiaD9Rt3lr8msYNIzfBIHNTrDHevqSUZjgPJdK4JzRivK4T6rI_p8AHuurVLm55wTXJ0JevJrPIfqd4Q/s1600/Creating+an+Office+App+-+Marc+Charmois+-+003+-+Azure+-+connection.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6JsmdvwuPInSTsaoTwVEW4wOG6RqapHG1jFLwOxj6oOHAkMKFV965Wz4lfA5wiaD9Rt3lr8msYNIzfBIHNTrDHevqSUZjgPJdK4JzRivK4T6rI_p8AHuurVLm55wTXJ0JevJrPIfqd4Q/s1600/Creating+an+Office+App+-+Marc+Charmois+-+003+-+Azure+-+connection.png"></a><br />
<br />
After logging in, you should see a screen notifying you that you do not have a subscription<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5FkvUgnz4eulljc0mNdN2eqhdc9bXgBC-M0wU-2cf1yfQClcYwS41Ugoo83A13KNl_lxQnNHMwbjAcyjgIB2xuJHM28_geKWAbhBNHdLl8KAudu_dsJWn9Lf73kUk6ZxaKJ0JUYugpVSM/s1600/Creating+an+Office+App+-+Marc+Charmois+-+004+-+Azure+-+connection.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5FkvUgnz4eulljc0mNdN2eqhdc9bXgBC-M0wU-2cf1yfQClcYwS41Ugoo83A13KNl_lxQnNHMwbjAcyjgIB2xuJHM28_geKWAbhBNHdLl8KAudu_dsJWn9Lf73kUk6ZxaKJ0JUYugpVSM/s1600/Creating+an+Office+App+-+Marc+Charmois+-+004+-+Azure+-+connection.png"></a><br />
<br />
Create a new subscription.<br />
If you're using a trial version of Office 365, you'll see a message telling you that Azure AD is limited to customers with paid services. You can still create a trial 30-day Azure subscription at no charge, but you'll need to perform a few extra steps:<br />
Select your country or region, and then choose Azure subscription.<br />
Enter your personal information. For verification purposes, enter a telephone number at which you can be reached, and specify whether you want to be sent a text message or called.<br />
Once you've received your verification code, enter it and choose Verify code.<br />
Enter payment information, check the agreement, and select Sign up.<br />
Your credit card will not be charged.<br />
Do not close or refresh your browser while your Azure subscription is being created.<br />
Once your Azure subscription is created, choose Portal.<br />
The Azure Tour appears. You can view it, or choose X to close it.<br />
You should now see all items in your Azure subscription. It lists a directory with the name of your Office 365 tenant.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">3.2 Register your App in Azure Management Portal</span><br />
<br />
Once signed in, follow these instructions:<br />
Click the Active Directory node in the left column and select the directory linked to your Office 365 subscription.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5zl-TKOwmBuoZv0LlQPuqsadh8sajs0D4ZLK2cbq20O_mttn0xErEOilnc2hprIU_1GgM0G8PqOa75wwh8efEj-kXBiZjFXW9IQ1jnKT3ZqgHx8XDw_0eehE4L7QsQgdf8PV-0nH4gz5e/s1600/Creating+an+Office+App+-+Marc+Charmois+-+01+-+Azure+-+Acrive+directory+Node.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5zl-TKOwmBuoZv0LlQPuqsadh8sajs0D4ZLK2cbq20O_mttn0xErEOilnc2hprIU_1GgM0G8PqOa75wwh8efEj-kXBiZjFXW9IQ1jnKT3ZqgHx8XDw_0eehE4L7QsQgdf8PV-0nH4gz5e/s1600/Creating+an+Office+App+-+Marc+Charmois+-+01+-+Azure+-+Acrive+directory+Node.png"></a><br />
<br />
Select the Applications tab and then Add at the bottom of the screen.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKD6Q4yWrXMXK8KiZLbLnklSGLDt484fntvvsaxPTrDtPlWi_bTH6Cy_7nDDKixekXWaNJzuDUfmKHEjJg66-NGJQog7KumqzDV5fJ85XpVIbjBUaw8kJudbuiied40pJH7KOayk_q4Yg1/s1600/Creating+an+Office+App+-+Marc+Charmois+-+02+-+Azure+-+Company+Acrive+directory.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKD6Q4yWrXMXK8KiZLbLnklSGLDt484fntvvsaxPTrDtPlWi_bTH6Cy_7nDDKixekXWaNJzuDUfmKHEjJg66-NGJQog7KumqzDV5fJ85XpVIbjBUaw8kJudbuiied40pJH7KOayk_q4Yg1/s1600/Creating+an+Office+App+-+Marc+Charmois+-+02+-+Azure+-+Company+Acrive+directory.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxuokWzBaDLzHmj0coc3r10F-Fqgf1QCOse_joKjk5_4R5U_XtwdGQRSOcNb6shji48QRQlFI8uGtWYUooCt-jhamHZrWGxB_EwJ_UMCix4rjcZamev_qlz1JJAEsXSRHXjfPAIUb8Yz7Z/s1600/Creating+an+Office+App+-+Marc+Charmois+-+03+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxuokWzBaDLzHmj0coc3r10F-Fqgf1QCOse_joKjk5_4R5U_XtwdGQRSOcNb6shji48QRQlFI8uGtWYUooCt-jhamHZrWGxB_EwJ_UMCix4rjcZamev_qlz1JJAEsXSRHXjfPAIUb8Yz7Z/s1600/Creating+an+Office+App+-+Marc+Charmois+-+03+-+Azure+-+Adding+an+App.png"></a><br />
<br />
On the pop-up, select Add an application my organization is developing.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGWxgQ6s48KUgREHBk0-NSzOLwnbMToOQQOn8SatUoQmLvfo8fgEDYtpt04bJD8xkwDD-vbgxhyphenhyphenb2MMPmpCwYkp-hCOhZ5E2mmNVJuc21h8fh9U0VgJpzbA0slcs5gRRElkrxrAnlIkOs/s1600/Creating+an+Office+App+-+Marc+Charmois+-+04+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGWxgQ6s48KUgREHBk0-NSzOLwnbMToOQQOn8SatUoQmLvfo8fgEDYtpt04bJD8xkwDD-vbgxhyphenhyphenb2MMPmpCwYkp-hCOhZ5E2mmNVJuc21h8fh9U0VgJpzbA0slcs5gRRElkrxrAnlIkOs/s1600/Creating+an+Office+App+-+Marc+Charmois+-+04+-+Azure+-+Adding+an+App.png"></a><br />
<br />
Choose an explicit name for your app,(I took Embed-OfficeGroup), and select Web application and/or web API as its Type. Then click the arrow to continue.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigidmxmOtGbgbYcUBMZJyamin_-blV3VMgMfCmRrvf7Ryo3yyFOKW08w84CCgel_h-HYKC6LsRJwvs_q44LBh83ROEg9_WcKFABiyuLVMibHhaLpfWU9vPWW8O50g4Z2hl2J7XDCMUAbrv/s1600/Creating+an+Office+App+-+Marc+Charmois+-+05+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigidmxmOtGbgbYcUBMZJyamin_-blV3VMgMfCmRrvf7Ryo3yyFOKW08w84CCgel_h-HYKC6LsRJwvs_q44LBh83ROEg9_WcKFABiyuLVMibHhaLpfWU9vPWW8O50g4Z2hl2J7XDCMUAbrv/s1600/Creating+an+Office+App+-+Marc+Charmois+-+05+-+Azure+-+Adding+an+App.png"></a><br />
<br />
The value of Sign-on URL is the URL where your application will be hosted. As I will call the App using JavaScript within a SharePoint page, I put the Url of my SharePoint site.<br />
The value of App ID URI is a unique identifier for Azure AD to identify your app. You can use http://{your_subdomain}/{YourAppName}, where {your_subdomain} is the subdomain of .onmicrosoft you specified while signing up for your Office 365 Developer Site. Then click the check mark to provision your application. For example, my Office 365 global admin account is, in this tutorial case:<br />
<br />
marc.charmois@marccharmois.onmicrosoft.com<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2_GsSGVQl841G1zFKNpwBi4mQR1glT6sW0PuQ7eUzu_co9BcmzUxOxrEjctznMPDGK6cjSpCTEPD1TdSVd1DIQEZz-s12_fipTxBn0zrFzZTVQ_p2s0ZGkvDebKnHORjWl-ao0RPAIuPU/s1600/Creating+an+Office+App+-+Marc+Charmois+-+06+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2_GsSGVQl841G1zFKNpwBi4mQR1glT6sW0PuQ7eUzu_co9BcmzUxOxrEjctznMPDGK6cjSpCTEPD1TdSVd1DIQEZz-s12_fipTxBn0zrFzZTVQ_p2s0ZGkvDebKnHORjWl-ao0RPAIuPU/s1600/Creating+an+Office+App+-+Marc+Charmois+-+06+-+Azure+-+Adding+an+App.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEganQszUPB_PHpR9-OvdobERwwQHUPQmhyBzf11syycWGdJqA7dtlnm1luLGa8vXrQDGvk5VGm3E2ZuStvb0Sdwa_zA6FWmeThNFiQxVIA8VkHfWDezJwkrCJ49mL6Ht7EnkpJP1-kPun9X/s1600/Creating+an+Office+App+-+Marc+Charmois+-+07+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEganQszUPB_PHpR9-OvdobERwwQHUPQmhyBzf11syycWGdJqA7dtlnm1luLGa8vXrQDGvk5VGm3E2ZuStvb0Sdwa_zA6FWmeThNFiQxVIA8VkHfWDezJwkrCJ49mL6Ht7EnkpJP1-kPun9X/s1600/Creating+an+Office+App+-+Marc+Charmois+-+07+-+Azure+-+Adding+an+App.png"></a><br />
<br />
Now that your app has been provisioned, select the Configure tab.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-uoJNKr1bTgSu_d7c0f8jRoRZ5jANaapXz7jy5w2Dyfrkm-DDoHfACxwK_LcAFLcPwJmQg5PdxgYOmk2nk0CuB86RXw253JYVyzHhiYzDpmmNob7-2gsEfSylTguAS63vcvrWtIQg09mV/s1600/Creating+an+Office+App+-+Marc+Charmois+-+08+-+Azure+-+Adding+an+App.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-uoJNKr1bTgSu_d7c0f8jRoRZ5jANaapXz7jy5w2Dyfrkm-DDoHfACxwK_LcAFLcPwJmQg5PdxgYOmk2nk0CuB86RXw253JYVyzHhiYzDpmmNob7-2gsEfSylTguAS63vcvrWtIQg09mV/s1600/Creating+an+Office+App+-+Marc+Charmois+-+08+-+Azure+-+Adding+an+App.png"></a><br />
<br />
Scroll down to the permissions to other applications section and click the Add application button.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinU6hFVnI5zfiejPi3fqifDzYdGFK70JmS3C44VB0ghkPGld9qOIcSt886wwFc9kptjd288KycCUeFwv6U05kAbF5BOdvKhajDwuYtUnTvYD5zHMMFFarw8bk-iqJsNEFcWMilGrRUIGGj/s1600/Creating+an+Office+App+-+Marc+Charmois+-+09+-+Azure+-+App+Configuration.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinU6hFVnI5zfiejPi3fqifDzYdGFK70JmS3C44VB0ghkPGld9qOIcSt886wwFc9kptjd288KycCUeFwv6U05kAbF5BOdvKhajDwuYtUnTvYD5zHMMFFarw8bk-iqJsNEFcWMilGrRUIGGj/s1600/Creating+an+Office+App+-+Marc+Charmois+-+09+-+Azure+-+App+Configuration.png"></a><br />
<br />
In this tutorial, we want our App to read the conversation of an Office group. To access to the Office Group we have to use the new Office 365 Unified API.<br />
Click the plus sign in the application's row and then click the check mark at the top right to add it. Then click the check mark at the bottom right to continue. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2wBzT9KJC3jCCnzPEWxXffbGATJKdSmdWZzoyKxU8v_4FwBJFr1hMIx-3a95eySlZ__mk3xofcnpADG0L_8fpMiN_Dts6HSO1lwbmNnXsKTS9Y0RynKGdBWQ5gldh3LesrFglSxXBEyVJ/s1600/Creating+an+Office+App+-+Marc+Charmois+-+007+-+Azure+-+configuration.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2wBzT9KJC3jCCnzPEWxXffbGATJKdSmdWZzoyKxU8v_4FwBJFr1hMIx-3a95eySlZ__mk3xofcnpADG0L_8fpMiN_Dts6HSO1lwbmNnXsKTS9Y0RynKGdBWQ5gldh3LesrFglSxXBEyVJ/s1600/Creating+an+Office+App+-+Marc+Charmois+-+007+-+Azure+-+configuration.png"></a><br />
<br />
In the Office 365 Unified API row, select Delegated Permissions, and in the selection list, choose Read All Groups.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk4-Mj5m_fHHOKp20pMntbvA_i022Vs2e77jepoiWmFcG-uuKkel_OXaSdbzq0iJDTK0CLxTPdV1rgluLx58xbqFrO6TtFPwy_dvfZL3pfWtqAXOCe8bg979oghSj4hI6x2YXA3tAq4egn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+008+-+Azure+-+configuration.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk4-Mj5m_fHHOKp20pMntbvA_i022Vs2e77jepoiWmFcG-uuKkel_OXaSdbzq0iJDTK0CLxTPdV1rgluLx58xbqFrO6TtFPwy_dvfZL3pfWtqAXOCe8bg979oghSj4hI6x2YXA3tAq4egn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+008+-+Azure+-+configuration.png"></a><br />
<br />
Click Save to save the app's configuration.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqzbjBVLaiyJZrZ2ZQRfjp7u2kA_u-pW4j5QVtWKsjEhD3vYDoSvl3XbYHsKmadhf9CtHneoeSIOZhq61c9M5M6Wo9zs60FhlUckIXobPCZe07csG1-wydVsHCYNMGvGQ3rHpNJnCxOum/s1600/Creating+an+Office+App+-+Marc+Charmois+-+12+-+Azure+-++App+Configuration.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqzbjBVLaiyJZrZ2ZQRfjp7u2kA_u-pW4j5QVtWKsjEhD3vYDoSvl3XbYHsKmadhf9CtHneoeSIOZhq61c9M5M6Wo9zs60FhlUckIXobPCZe07csG1-wydVsHCYNMGvGQ3rHpNJnCxOum/s1600/Creating+an+Office+App+-+Marc+Charmois+-+12+-+Azure+-++App+Configuration.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz8XrigtFq279kMm33fjSQMRli2r83FrM7fDUaf6_NHJuBI9EatVKQsAij16fFMk-xN3sk7szW0mLJ4jOM7GpspT0G4A6kuYvBFWq1SVAj_OItKMXO3ws47jOncuFLlh25yao0DvP8-BZG/s1600/Creating+an+Office+App+-+Marc+Charmois+-+13+-+Azure+-++App+Saving.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz8XrigtFq279kMm33fjSQMRli2r83FrM7fDUaf6_NHJuBI9EatVKQsAij16fFMk-xN3sk7szW0mLJ4jOM7GpspT0G4A6kuYvBFWq1SVAj_OItKMXO3ws47jOncuFLlh25yao0DvP8-BZG/s1600/Creating+an+Office+App+-+Marc+Charmois+-+13+-+Azure+-++App+Saving.png"></a><br />
<br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">3.3 Configure your app to allow the OAuth 2.0 implicit grant flow</span><br />
<br />
<br />
In order to get an access token for Office 365 API requests, your application will use the OAuth implicit grant flow. You need to update the application's manifest to allow the OAuth implicit grant flow because it is not allowed by default.<br />
Select the Configure tab of your application's entry in the Azure Management Portal.<br />
<br />
<br />
Using the Manage Manifest button in the drawer, download the manifest file for the application and save it to your computer.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQGVGjfNTU0OtkrktU_es4DrJK1xOxi3Spwo-lb1EzCTwAgtCqX0QXrzZH4Ak-Ecbvsy8q_wWV3-40yG2KHgLW3K_WgpB5FgqQABMY7kq0GJeNJWYWYOzZpg0HibBaTQFJiVxWIjKDezd4/s1600/Creating+an+Office+App+-+Marc+Charmois+-+14+-+Azure+-++App+Saved.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQGVGjfNTU0OtkrktU_es4DrJK1xOxi3Spwo-lb1EzCTwAgtCqX0QXrzZH4Ak-Ecbvsy8q_wWV3-40yG2KHgLW3K_WgpB5FgqQABMY7kq0GJeNJWYWYOzZpg0HibBaTQFJiVxWIjKDezd4/s1600/Creating+an+Office+App+-+Marc+Charmois+-+14+-+Azure+-++App+Saved.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEDjB6J3dCA58qPg2ZOXfinWCMdwtCOFvuahJb3DcDkPIyiC0CwQqfd3YVfnM4-0Q2SQr6PrpCGSx4gZqr-o1eiH86YQzxDy0aoqGNeXwA2AU_LLMBm36Ysfl58ZjyGnY4Tp2R9WEW-Ykj/s1600/Creating+an+Office+App+-+Marc+Charmois+-+15+-+Azure+-++Download+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEDjB6J3dCA58qPg2ZOXfinWCMdwtCOFvuahJb3DcDkPIyiC0CwQqfd3YVfnM4-0Q2SQr6PrpCGSx4gZqr-o1eiH86YQzxDy0aoqGNeXwA2AU_LLMBm36Ysfl58ZjyGnY4Tp2R9WEW-Ykj/s1600/Creating+an+Office+App+-+Marc+Charmois+-+15+-+Azure+-++Download+App+manifest.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4dfw6Et6x4MmXDx6l3SXwQJz2G_lIhm5No3AlMCeiy6E7WgzU9KjOAls1b0wclYge1S9QXiU5T7p91Y8bgRmd1Pl9jC2mkcwtj4eIIFxzRp4UB4KsSGDDLC8YL3ZRQNjfsVR4qgQC5hvn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+16+-+Azure+-++Download+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4dfw6Et6x4MmXDx6l3SXwQJz2G_lIhm5No3AlMCeiy6E7WgzU9KjOAls1b0wclYge1S9QXiU5T7p91Y8bgRmd1Pl9jC2mkcwtj4eIIFxzRp4UB4KsSGDDLC8YL3ZRQNjfsVR4qgQC5hvn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+16+-+Azure+-++Download+App+manifest.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL5-Y02JTE68pUu4kAV8IhPkCgtt1PaZrkXtV62kxk4DZgGGoYibynxZS7bi0lipXdfj-g4wXrA2gtE07_CeOBYGw9h7qamMESJWFpd-LyWM96PYmLiKT0C9aoc8vBw9PdydIqJoj_oY-r/s1600/Creating+an+Office+App+-+Marc+Charmois+-+17+-+Azure+-++Download+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL5-Y02JTE68pUu4kAV8IhPkCgtt1PaZrkXtV62kxk4DZgGGoYibynxZS7bi0lipXdfj-g4wXrA2gtE07_CeOBYGw9h7qamMESJWFpd-LyWM96PYmLiKT0C9aoc8vBw9PdydIqJoj_oY-r/s1600/Creating+an+Office+App+-+Marc+Charmois+-+17+-+Azure+-++Download+App+manifest.png"></a><br />
<br />
Open the manifest file with a text editor. Search for the oauth2AllowImplicitFlow property. By default it is set to false; change it to true and save the file.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjatKiaOnl3p0QPKQKOY09npalKkSL4WZTvwtnXD91fDXXENy30KJWLKUrsFFS8pFjYZH41T4HmwDXC9C-YSqIcTrQGgoTMXoiTId5AEwTKC4wCybAULeB2p-YKglpJX8XKqFXIa_GQ5QRk/s1600/Creating+an+Office+App+-+Marc+Charmois+-+17+-+Azure+-++Modifying+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjatKiaOnl3p0QPKQKOY09npalKkSL4WZTvwtnXD91fDXXENy30KJWLKUrsFFS8pFjYZH41T4HmwDXC9C-YSqIcTrQGgoTMXoiTId5AEwTKC4wCybAULeB2p-YKglpJX8XKqFXIa_GQ5QRk/s1600/Creating+an+Office+App+-+Marc+Charmois+-+17+-+Azure+-++Modifying+App+manifest.png"></a><br />
<br />
Using the Manage Manifest button, upload the updated manifest file.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSMBR-NeOz3-_lLmSybgxSn4zQaQ4ZigIKYSkCRs3KyCeMzknBkiZa6CffX_RjpueaFpP7jus1NClKghubHa5ScTnDUTOiSx6hHDFguGLDGs_iwOvyJleAA-vNwWZQibO0bd4nbDCNep1G/s1600/Creating+an+Office+App+-+Marc+Charmois+-+18+-+Azure+-++Uploading+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSMBR-NeOz3-_lLmSybgxSn4zQaQ4ZigIKYSkCRs3KyCeMzknBkiZa6CffX_RjpueaFpP7jus1NClKghubHa5ScTnDUTOiSx6hHDFguGLDGs_iwOvyJleAA-vNwWZQibO0bd4nbDCNep1G/s1600/Creating+an+Office+App+-+Marc+Charmois+-+18+-+Azure+-++Uploading+App+manifest.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_J9_objyFnxNvtSRytAdEB_ZhyphenhyphenM3PfKIXZomSkYiqGI1eLvb8K3hI-t1N6OJfcym7Fpk7q164MEHMSGtcqsYyZ5ld2SfnqDF6FaPzEkgVRE9YFWHKXbTSwa6p9bg1i9ExH_SE3hPgdVch/s1600/Creating+an+Office+App+-+Marc+Charmois+-+21+-+Azure+-++Uploading+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_J9_objyFnxNvtSRytAdEB_ZhyphenhyphenM3PfKIXZomSkYiqGI1eLvb8K3hI-t1N6OJfcym7Fpk7q164MEHMSGtcqsYyZ5ld2SfnqDF6FaPzEkgVRE9YFWHKXbTSwa6p9bg1i9ExH_SE3hPgdVch/s1600/Creating+an+Office+App+-+Marc+Charmois+-+21+-+Azure+-++Uploading+App+manifest.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhbjANqBXTL_-w27iJypOUX-L_zwoPV43AbNuf8nJHJY1NiaAaFL0PLq3AS-z_u95VU0_CRwDfykZGVHLsIKgTxb2iCYXkefS2uqibO9XSR53enjhfkYiwQqgvFbzDcxy_j-BbYCdcr7p4/s1600/Creating+an+Office+App+-+Marc+Charmois+-+22+-+Azure+-++Uploading+App+manifest.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhbjANqBXTL_-w27iJypOUX-L_zwoPV43AbNuf8nJHJY1NiaAaFL0PLq3AS-z_u95VU0_CRwDfykZGVHLsIKgTxb2iCYXkefS2uqibO9XSR53enjhfkYiwQqgvFbzDcxy_j-BbYCdcr7p4/s1600/Creating+an+Office+App+-+Marc+Charmois+-+22+-+Azure+-++Uploading+App+manifest.png"></a><br />
<br />
You've now successfully registered your application with Azure AD.<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">4 - Coding the SharePoint page (physical App) that's using the Azure App (Virtual App)</div><br />
<span style="color: #e9ab17; margin-left: 50px;">4.1 Creating the app.html page</span><br />
<br />
In your 0ffice 365 environment, create a new site collection. Once it's done, navigate to the "Site Assets" library. Open the library in Explorer mode<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMxx-_OF4IMX8PgirxjnI2FjBJRojdvLEGYI3tDfFFkQlk4xW85D1pN56uKKB6Z4gpuwPgZfpSXXgPzTyLUkYShxYnkqBoeDJDb19LowJLckkA3nSulDAIPr1cwMeL5HbKuBB_fVxjUO-h/s1600/Creating+an+Office+App+-+Marc+Charmois+-+23+-+SharePoint+Online+-++creatin+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMxx-_OF4IMX8PgirxjnI2FjBJRojdvLEGYI3tDfFFkQlk4xW85D1pN56uKKB6Z4gpuwPgZfpSXXgPzTyLUkYShxYnkqBoeDJDb19LowJLckkA3nSulDAIPr1cwMeL5HbKuBB_fVxjUO-h/s1600/Creating+an+Office+App+-+Marc+Charmois+-+23+-+SharePoint+Online+-++creatin+the+app.html+page.png"></a><br />
<br />
<br />
and using the window navigate to the root folder of your site. Create an html page within the folder and name it app.html<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNaWfeRVljzuWOjOsoy4Aj9FJfl0gMXOQbM0Vuw0C__87uEfIAQ8r3WvHKQRizX7ko_LnNGtOhDF_AFyTRIvWqjJZFd7qPd-yH9HqWBxvLCV_jh6xBLvMwPJbQUOXGbIVhQVUaEUYjP2Xn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+24+-+SharePoint+Online+-++creating+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNaWfeRVljzuWOjOsoy4Aj9FJfl0gMXOQbM0Vuw0C__87uEfIAQ8r3WvHKQRizX7ko_LnNGtOhDF_AFyTRIvWqjJZFd7qPd-yH9HqWBxvLCV_jh6xBLvMwPJbQUOXGbIVhQVUaEUYjP2Xn/s1600/Creating+an+Office+App+-+Marc+Charmois+-+24+-+SharePoint+Online+-++creating+the+app.html+page.png"></a><br />
<br />
You can now open this page with Visual Studio or Notepad ++ and start to programm the displaying of the Office Group conversation <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh39OAr1-X6Q53WojMmq7SWRYUopgwuu4jShIpcfoQalb02VjV71h6zyEqP293KY0lK7neTIA7DdUOEbIJv7CykmS6Kih87zWuynzd4qDRCWP4bTml5hU2GpVJx-a44Vva37AXgNwwPF7v1/s1600/Creating+an+Office+App+-+Marc+Charmois+-+25+-+SharePoint+Online+-++programming+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh39OAr1-X6Q53WojMmq7SWRYUopgwuu4jShIpcfoQalb02VjV71h6zyEqP293KY0lK7neTIA7DdUOEbIJv7CykmS6Kih87zWuynzd4qDRCWP4bTml5hU2GpVJx-a44Vva37AXgNwwPF7v1/s1600/Creating+an+Office+App+-+Marc+Charmois+-+25+-+SharePoint+Online+-++programming+the+app.html+page.png"></a><br />
<br />
<span style="background-color:yellow">You can find the complete app.html page</span> in the <a href="https://github.com/MarcCharmois/Embed-Office-Group-into-SharePoint-Online">dedicated Github repository</a><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">4.2 Determine the resource endpoint</span><br />
<br />
In order to make any API requests, you'll need to determine the correct endpoint of the resource you want to use. The endpoint you'll use is determined by what information you want from Office 365. Refer to the API reference documentation to get the endpoint you want.<br />
Mail API reference<br />
Contacts API reference<br />
Calendar API reference<br />
Files API reference<br />
Alternatively, you can take advantage of the Office 365 unified API (preview) to access all of the APIs from a single endpoint, https://graph.microsoft.com. Refer to the Office 365 unified API reference to browse all of the supported endpoints.<br />
For this sample, we will use the Office 365 unified API to get a conversation of an Office Group. The endpoint for this operation is <br />
https://graph.microsoft.com/beta/{your_domain}/groups, where {your_domain} is the domain you specified while signing up for your Office 365 Developer Site. In my case marccharmois.onmicrosoft.com. <br />
<br />
My endpoint is: https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">4.3 Get an access token from Azure</span><br />
<br />
Office 365 uses OAuth 2.0 tokens issued by Azure AD to authenticate JavaScript clients. Tokens are obtained using the OAuth 2.0 implicit grant flow. Using implicit grant, your application requests an access token from Azure AD for the currently signed-in user by sending the user to an authorization URL where the user signs in with their Office 365 credentials and then is redirected back to the app with the access token in the URL.<br />
The following function builds the authorization URL and navigates to it to begin the authentication process.<br />
<br />
<pre class="code-standard">function requestToken() {
// Change clientId and replyUrl to reflect your app's values
// found on the Configure tab in the Azure Management Portal.
// Also change {your_subdomain} to your subdomain for both endpointUrl and resource.
var clientId = 'e77659cc-bf72-4276-bd33-bdd876660a74';//ID of your App in Azure
var replyUrl = 'https://marccharmois.sharepoint.com/sites/intranet/app.html'; //my sharepoint page that requests an oauth 2 authentification and data
//It is also referenced in the REPLY URL field of my App in Azure
var endpointUrl = 'https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups';
//var endpointUrl = 'https://marccharmois-my.sharepoint.com/_api/v1.0/me/files';//getting files from SharePoint
//var endpointUrl = 'https://outlook.office.com/api/V1.0/me/messages';//getting messages from outlook
var resource = "https://graph.microsoft.com/";
//var resource = "https://marccharmois-my.sharepoint.com"; //getting files from SharePoint
//var resource = "https://outlook.office.com"; //getting messages from outlook
var authServer = 'https://login.windows.net/common/oauth2/authorize?';
//var authServer = 'https://login.microsoftonline.com/common/oauth2/authorize?';//this works either
var responseType = 'token';
var url = authServer +
"response_type=" + encodeURI(responseType) + "&" +
"client_id=" + encodeURI(clientId) + "&" +
"resource=" + encodeURI(resource) + "&" +
"redirect_uri=" + encodeURI(replyUrl);
window.location = url;
}
</pre><br />
At this point what's going on? <br />
When I use this function, I am redirected to the same page, but with the acces token in the Url as a parameter: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCwcQE0eDHDLl3wEdwsZ_OW-YeP_yq7IwprlL5duc7JU6JSLm_2fML6mIAho_SGOx9rb2gcZuj91FGewUiteCMQV3NAsUyTOZeWPmvDFAuSy_vLpI5CbZhNJngXu-_W6QOlJzTuJ1OIrqz/s1600/Creating+an+Office+App+-+Marc+Charmois+-+26+-+SharePoint+Online+-++programming+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCwcQE0eDHDLl3wEdwsZ_OW-YeP_yq7IwprlL5duc7JU6JSLm_2fML6mIAho_SGOx9rb2gcZuj91FGewUiteCMQV3NAsUyTOZeWPmvDFAuSy_vLpI5CbZhNJngXu-_W6QOlJzTuJ1OIrqz/s1600/Creating+an+Office+App+-+Marc+Charmois+-+26+-+SharePoint+Online+-++programming+the+app.html+page.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxN4GeuBjF54OXrVGT7IcHP1isgln_2DI6Uc7w2Uq-GgKk3mm-4WiSHUVvZSu3BW0icTwtPZdDLCqEWM0QxG6mrXvs1sQolSEUL49tdbruSWJOz6U_Vp5nx8K6zHeB5OPUAePbLuCZlMYE/s1600/Creating+an+Office+App+-+Marc+Charmois+-+27+-+SharePoint+Online+-++programming+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxN4GeuBjF54OXrVGT7IcHP1isgln_2DI6Uc7w2Uq-GgKk3mm-4WiSHUVvZSu3BW0icTwtPZdDLCqEWM0QxG6mrXvs1sQolSEUL49tdbruSWJOz6U_Vp5nx8K6zHeB5OPUAePbLuCZlMYE/s1600/Creating+an+Office+App+-+Marc+Charmois+-+27+-+SharePoint+Online+-++programming+the+app.html+page.png"></a><br />
<br />
I can even display the token <br />
<br />
<pre class="code-standard">var urlParameterExtraction = new (function () {
function splitQueryString(queryStringFormattedString) {
var split = queryStringFormattedString.split('&');
// If there are no parameters in URL, do nothing.
if (split == "") {
return {};
}
var results = {};
// If there are parameters in URL, extract key/value pairs.
for (var i = 0; i < split.length; ++i) {
var p = split[i].split('=', 2);
if (p.length == 1)
results[p[0]] = "";
else
results[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return results;
}
// Split the query string (after removing preceding '#').
this.queryStringParameters = splitQueryString(window.location.hash.substr(1));
})();
function displayToken(){
// Extract token from urlParameterExtraction object.
var token = urlParameterExtraction.queryStringParameters['access_token'];
alert('token : \n'+ token);
}
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqNurNYVZVUISbjP1oO9rMoOCFkFsF6FhzEl-N9zL9B6aaeomIU83SGa7ddFPwLyG1aPJtnkwkgZYyce_tS__waU0XxgpHPHR5Jn5JPM5UJNQNQemnK4rpLL22EHcsJk2y2jlfUe0ne3BJ/s1600/Creating+an+Office+App+-+Marc+Charmois+-+28+-+SharePoint+Online+-++programming+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqNurNYVZVUISbjP1oO9rMoOCFkFsF6FhzEl-N9zL9B6aaeomIU83SGa7ddFPwLyG1aPJtnkwkgZYyce_tS__waU0XxgpHPHR5Jn5JPM5UJNQNQemnK4rpLL22EHcsJk2y2jlfUe0ne3BJ/s1600/Creating+an+Office+App+-+Marc+Charmois+-+28+-+SharePoint+Online+-++programming+the+app.html+page.png"></a><div style="clear:both"></div>Now that I have the token, here is the code to request the Office 365 Unified API to get all the specific conversation of an Office Group:
<pre class="code-standard">function getToken(){
var token = urlParameterExtraction.queryStringParameters['access_token'];
return token;
}
function getGroupsFromO365() {
try
{
//var endpointUrl = 'https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups'; //getting all groups to get the ID of the group you want
//var endpointUrl = 'https://marccharmois-my.sharepoint.com/_api/v1.0/me/files';//getting files from SharePoint
//var endpointUrl = 'https://outlook.office.com/api/V1.0/me/messages';//getting messages from SharePoint
var endpointUrl = "https://graph.microsoft.com/beta/contoso.com/groups('4eba7454-b490-46ae-bb5e-774efaec7c6f')/conversations('AAQkADZjOTdkMTIwLWFjNTItNDUyYy05MTc4LTg1NmJmMDk1MjYxOQAQAD_Ql6WI-GlHs3VmVZsV3QA=')/threads('AAQkADZjOTdkMTIwLWFjNTItNDUyYy05MTc4LTg1NmJmMDk1MjYxOQMkABAAP5CXpYj8aUezdWZVmxXdABAAP5CXpYj8aUezdWZVmxXdAA==')/Posts";
var xhr = new XMLHttpRequest();
xhr.open("GET", endpointUrl);
var myToken = getToken();
// The APIs require an OAuth access token in the Authorization header, formatted like this: 'Authorization: Bearer <token>'.
xhr.setRequestHeader("Authorization", "Bearer " + myToken);
// Process the response from the API.
xhr.onload = function () {
if (xhr.status == 200) {
//alert('data received');
var message="";
var object = JSON.parse(xhr.response);
for(i=0;i<object.value.length;i++){
message+='From: ' + object.value[i].From.EmailAddress.Name + '<BR>';
message+='At: ' + object.value[i].CreatedDateTime + '<BR>';
message+= object.value[i].Body.Content + '<BR>';
}
//var formattedResponse = JSON.stringify(JSON.parse(xhr.response), undefined, 2);
document.getElementById("results").innerHTML = message;
} else {
document.getElementById("results").textContent = "HTTP " + xhr.status + "<BR>" + xhr.response;
}
}
// Make request.
xhr.send();
}
catch (err)
{
document.getElementById("results").textContent = "Exception: " + err.message;
}
}
</pre><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8Aa5vcR61GTZpduJWOydC8Focs5gDzlRru8DHQOJOEKhC35ANiwxizcQjonDLWbc6dNM6o0OnU3abQTazv1MDnmSR6YeXXP1AZitePjY14JdgzKyMpLZTE7JtZYTUShk3MIy_nvWdnnhN/s1600/Creating+an+Office+App+-+Marc+Charmois+-+29+-+SharePoint+Online+-++programming+the+app.html+page.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8Aa5vcR61GTZpduJWOydC8Focs5gDzlRru8DHQOJOEKhC35ANiwxizcQjonDLWbc6dNM6o0OnU3abQTazv1MDnmSR6YeXXP1AZitePjY14JdgzKyMpLZTE7JtZYTUShk3MIy_nvWdnnhN/s1600/Creating+an+Office+App+-+Marc+Charmois+-+29+-+SharePoint+Online+-++programming+the+app.html+page.png"></a><div style="clear:both"></div>Now, you can display this app.html into any SharePoint page by calling it within an iframe tag...
<div style="clear:both"></div>
<pre class="code-standard">
<span style="display:block;margin-bottom:3px;font-size;13px;">Embedded Office Group Conversation:</span> <iframe src="https://marccharmois.sharepoint.com/sites/intranet/app.html" style="height:400px;width=300px;border:solid 1px silver"></iframe>
</pre>
<div style="clear:both"></div>As I did for this Web Part page;
<div style="clear:both"></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiTapWOq7bgctB9BpAcoPBZxed_90qCiYRUwhnWvkliKut1P-Wcrea7X1IfzMvUEeNFLjsk9oSViyYB4YR7UbOheGpoOf5uUZPBwTHOMqyNy88KlEw02glit4ePAo9_0oMVmCsdYvODNj2/s1600/Creating+an+Office+App+-+Marc+Charmois+-+002+-+Office+Group+Conversation+embedded+into+SharePoint+Online.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiTapWOq7bgctB9BpAcoPBZxed_90qCiYRUwhnWvkliKut1P-Wcrea7X1IfzMvUEeNFLjsk9oSViyYB4YR7UbOheGpoOf5uUZPBwTHOMqyNy88KlEw02glit4ePAo9_0oMVmCsdYvODNj2/s1600/Creating+an+Office+App+-+Marc+Charmois+-+002+-+Office+Group+Conversation+embedded+into+SharePoint+Online.png"></a>
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">5 - Aknowledgements </div><ul><li><a href="https://msdn.microsoft.com/en-us/office/office365/howto/create-web-apps-using-CORS-to-access-files-in-Office-365">Create JavaScript web apps using CORS to access Office 365 APIs</a></li>
<li><a href="https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment">Set up your Office 365 development environment</a></li>
<li><a href="https://github.com/OfficeDev/TrainingContent/blob/master/O3651/O3651-7%20Setting%20up%20your%20Developer%20environment%20in%20Office%20365/Lab.md">Setting up your Development Environment in Office 365</a></li>
<li><a href="https://msdn.microsoft.com/en-us/office/office365/howto/get-started-with-office-365-unified-api">Get started with Office 365 unified API</a></li>
<li><a href="https://msdn.microsoft.com/office/office365/HowTo/groups-rest-operations#GetConversations">Office 365 Groups REST API reference </a></li>
</ul>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com1tag:blogger.com,1999:blog-4357140756496246910.post-44644913064337204862015-10-30T18:06:00.002+01:002019-09-05T21:09:29.201+02:00SharePoint 2016 Installation<div class="h2-paragraph">
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">Microsoft released the IT Preview of SharePoint 2016 on August 2015 24th. I will, as usual, post, a step by step installation guide for installing SharePoint 2016 in order to build <span style="background-color: yellow;">a trial or development environment</span>. The aim of this guide is to be as detailed as possible with all the screen shots in order:<br />
<ul><li>non technical person (trainer, non technical IT pro, etc.) to be able to mount a trial environment.</li>
<li>All the installation will be on <span style="background-color: yellow;">a single virtual machine</span></li>
<li>this tutorial will use the trial versions of the products (OS, SQL Server) so as trainers or developers to be able to <span style="background-color: yellow;">build a SharePoint 2016 environment for free</span>. </li>
<li>I will use the most simple <span style="background-color: yellow;">features so as the installation to be as fast and simple as possible (sort of installation for dummies). For example, I will use the Administrator local account for installing all the softwares and to be the only service account</span> (that is a very bad practice for a real environment)</li>
</ul><br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">1 - Deciding for the best configuration</div>If you check <a href="http://blogs.technet.com/b/wbaer/archive/2015/05/12/what-s-new-in-sharepoint-server-2016-installation-and-deployment.aspx">the post of Bill Baer</a>, the SharePoint Senior Product Marketing Manager, that gives the recommendations, in our case, for a trial or development environment:<br />
<div style="margin-left:30px"><h1 style="background-color: white; clear: both; color: #414042; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 1.6em; font-weight: 100; line-height: 1.3;">System Requirements</h1><table border="0" cellpadding="0" cellspacing="0" style="background-color: white; border-bottom-color: rgb(225, 225, 225); border-collapse: collapse; border-style: none none solid; border-width: 0px 0px 1px; color: #2a2a2a; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 12.96px; line-height: 19.44px; margin-left: 1px;"><tbody>
<tr><td style="vertical-align: top;" valign="top" width="156"><div style="padding: 0px;"><strong><span style="color: #333333;">Scenario</span></strong></div></td><td style="vertical-align: top;" valign="top" width="156"><div style="padding: 0px;"><strong><span style="color: #333333;">Deployment type and scale</span></strong></div></td><td style="vertical-align: top;" valign="top" width="108"><div style="padding: 0px;"><strong><span style="color: #333333;">Processor</span></strong></div></td><td style="vertical-align: top;" valign="top" width="98"><div style="padding: 0px;"><strong><span style="color: #333333;">RAM</span></strong></div></td><td style="vertical-align: top;" valign="top" width="262"><div style="padding: 0px;"><strong><span style="color: #333333;">Hard disk</span></strong></div></td></tr>
<tr><td style="vertical-align: top;" valign="top" width="156"><div style="padding: 0px;"><span style="color: #666666;"><strong>Database server running a single SQL instance</strong></span></div></td><td style="vertical-align: top;" valign="top" width="156"><div style="padding: 0px;"><span style="color: #666666;">Development or evaluation installation with the minimum recommended services</span></div></td><td style="vertical-align: top;" valign="top" width="108"><div style="padding: 0px;"><span style="color: #666666;">64-bit, 4 cores</span></div></td><td style="vertical-align: top;" valign="top" width="98"><div style="padding: 0px;"><span style="color: #666666;">12-16 GB</span></div></td><td style="vertical-align: top;" valign="top" width="262"><div style="padding: 0px;"><span style="color: #666666;">80 GB for system drive</span></div><div style="padding: 0px;"><span style="color: #666666;">100 GB for second drive</span></div></td></tr>
</tbody></table></div><br />
--> So be sure to have a computer with at least <span style="background-color: yellow;">16 Go of RAM with 200 Go of free disk space</span>. <br />
<br />
<br />
<div style="margin-left:30px"><h1 style="background-color: white; clear: both; color: #414042; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 1.6em; font-weight: 100; line-height: 1.3;">Operating System Requirements</h1><div style="background-color: white; color: #2a2a2a; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 12.96px; line-height: 19.44px;">SharePoint Server 2016 is supported on Windows Server 2012 R2 and Windows Server Technical Preview. Evaluation copies of both operating systems can be downloaded from the TechNet Evaluation Center:</div><ul style="background-color: white; color: #2a2a2a; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 12.96px; line-height: 19.44px;"><li style="font-size: 1.1em; margin-left: -25px;">Windows Server 2012 R2<br />
<a href="http://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2012-r2" style="color: #00749e; cursor: pointer; outline: none; text-decoration: none;">http://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2012-r2</a></li>
<li style="font-size: 1.1em; margin-left: -25px;">Windows Server Technical Preview<br />
<a href="http://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-technical-preview" style="color: #00749e; cursor: pointer; outline: none; text-decoration: none;">http://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-technical-preview</a></li>
</ul></div>--> For this tutorial, I will use <span style="background-color: yellow;">Windows Server 2012 R2</span>, because the version of SharePoint 2016 is already a preview. I don't take the risk of mixing 2 preview products (<a href="https://technet.microsoft.com/en-us/library/mt346109(v=office.16).aspx#Anchor_12" >there is a known issue when using Windows Server 2016 Technical Preview 3 regarding the IIS role when running the SharePoint 2016 preview prerequisites Installation</a> (<a href="http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2015/08/24/sharepoint-2016-installation-first-look.aspx">thanks to Corey Roth</a>). <br />
<br />
<div style="margin-left:30px"><h1 style="background-color: white; clear: both; color: #414042; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 1.6em; font-weight: 100; line-height: 1.3;">SharePoint Database Server Requirements</h1><div style="background-color: white; color: #2a2a2a; font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 12.96px; line-height: 19.44px;">SharePoint Server 2016 requires SQL Server 2014 for its databases. You can download SQL Server from the TechNet Evaluation Center at <a href="http://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2014" style="color: #00749e; cursor: pointer; outline: none; text-decoration: none;">http://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2014</a>. In addition SharePoint Server 2016 will support SQL Server 2016. For additional information on SQL Server 2016 see also <a href="http://www.microsoft.com/en-us/server-cloud/products/sql-server-2016/" style="color: #00749e; cursor: pointer; outline: none; text-decoration: none;" title="http://www.microsoft.com/en-us/server-cloud/products/sql-server-2016/">http://www.microsoft.com/en-us/server-cloud/products/sql-server-2016/</a>.</div></div><br />
--> For this tutorial, I will use <span style="background-color: yellow;">SQL Server 2014 </span>, because as said before, the version of SharePoint 2016 is already a preview. I don't take the risk of mixing 2 preview products. (even if SQL Server 2016 seems to be much faster than SQL 2014)<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">2 - Creating the Virtual Machine</div><div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">2.1 - Download Windows Server 2012 R2 Evaluation </div>Start downloading a <a href="http://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2012-r2">180 days evaluation version of Windows Server 2012 R2</a>. You will have to sign in to obtain. <br />
<br />
Choose the ISO option<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf-g68Q71gZaFJHzBGyAyH4mUUkldVPdag8F9w3i4igr2HpYaVW9ko_zxcyvFnlPp7aNZ7BTW08RzYNC0vNpcyKlRKi_SzM1ttyCbjKhNlTSIpEkr9xsLpQSYv-9QAskW23EZj_d495Aoi/s1600/SharePoint+2016+installation+-+marc+charmois+01+-+downloading+Windows+server+2012+R2.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf-g68Q71gZaFJHzBGyAyH4mUUkldVPdag8F9w3i4igr2HpYaVW9ko_zxcyvFnlPp7aNZ7BTW08RzYNC0vNpcyKlRKi_SzM1ttyCbjKhNlTSIpEkr9xsLpQSYv-9QAskW23EZj_d495Aoi/s1600/SharePoint+2016+installation+-+marc+charmois+01+-+downloading+Windows+server+2012+R2.png"></a><br />
<br />
It is better to use an English version for an evaluation purpose so as to be sure to have the system messages in English. There is much more informations in the search engine for English messages. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtTVVjec0yUeIrgVAwihs-Tz0w0siRIcjMqGzmjJX6Wn_f9ueMUobiA-7itZf3QCl-AuhSqmN-WluZor8wnZNl8LlXuiyt8wmVd0iBcRGIUnjb7X74jgSLgy-VZaYrZLgQ9vFxT8uLVHZt/s1600/SharePoint+2016+installation+-+marc+charmois+02+-+downloading+Windows+server+2012+R2.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtTVVjec0yUeIrgVAwihs-Tz0w0siRIcjMqGzmjJX6Wn_f9ueMUobiA-7itZf3QCl-AuhSqmN-WluZor8wnZNl8LlXuiyt8wmVd0iBcRGIUnjb7X74jgSLgy-VZaYrZLgQ9vFxT8uLVHZt/s1600/SharePoint+2016+installation+-+marc+charmois+02+-+downloading+Windows+server+2012+R2.png"></a><br />
<br />
To the question do you want System Center components included, choose "No". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK5KVosjvfCjMnGQYAIlji2MrsYdl32wsYtHHi8lk3TTeSewY7ZtOk58dKsd_HlrZDKqfi-g6D7r_JZAQiAHZ-pwfUieF6H0h9cRHqAfFzyvHXsFfiLX3ZBtrrljqLqR42SXvsH45Jj2ev/s1600/SharePoint+2016+installation+-+marc+charmois+030+-+downloading+Windows+server+2012+R2.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK5KVosjvfCjMnGQYAIlji2MrsYdl32wsYtHHi8lk3TTeSewY7ZtOk58dKsd_HlrZDKqfi-g6D7r_JZAQiAHZ-pwfUieF6H0h9cRHqAfFzyvHXsFfiLX3ZBtrrljqLqR42SXvsH45Jj2ev/s1600/SharePoint+2016+installation+-+marc+charmois+030+-+downloading+Windows+server+2012+R2.png"></a><br />
<br />
Then, you can finally download the .ISO file of Windows Server 2012 R2<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UUOjfyUjqoZW5R3x-TMV8ZC-tYktuDZuIvBh04NcrndAlQUzZbM8EXNHGJuLsf5zE0KRwUrmgCT6VkUwbisaZlCgtuWL3uvRxmssG2skNzTOHm3emrDaqsi0p9c7hXdwkPpWfhJ_LvV4/s1600/SharePoint+2016+installation+-+marc+charmois+04+-+downloading+Windows+server+2012+R2.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UUOjfyUjqoZW5R3x-TMV8ZC-tYktuDZuIvBh04NcrndAlQUzZbM8EXNHGJuLsf5zE0KRwUrmgCT6VkUwbisaZlCgtuWL3uvRxmssG2skNzTOHm3emrDaqsi0p9c7hXdwkPpWfhJ_LvV4/s1600/SharePoint+2016+installation+-+marc+charmois+04+-+downloading+Windows+server+2012+R2.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">2.2 - Creating the Virtual Machine </div>Download the <a href="https://www.vmware.com/products/player/playerpro-evaluation.html">VMWare player trial version</a><br />
<br />
When VMWare is installed, open it and Click the "Create New Virtual Machine" button.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmkR3jP1T9UykN1O-S_dWcmRHcED_LNQBAvWQKy_mUdpJO6Vl56ypx2NFFJus0cj3zj3M6U4P51f6Z1LshKQIMUSHxtTffeJzc4d7UJw8GrdYtO1FgiS39kAzQmXQAoTfDzNNtXf3w0Frs/s1600/SharePoint+2016+installation+-+marc+charmois+05+-+create+a+new+vmWare+virtual+machine.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmkR3jP1T9UykN1O-S_dWcmRHcED_LNQBAvWQKy_mUdpJO6Vl56ypx2NFFJus0cj3zj3M6U4P51f6Z1LshKQIMUSHxtTffeJzc4d7UJw8GrdYtO1FgiS39kAzQmXQAoTfDzNNtXf3w0Frs/s1600/SharePoint+2016+installation+-+marc+charmois+05+-+create+a+new+vmWare+virtual+machine.png"></a><br />
<br />
Then, add the reference to the .iso file of the Windows Server 2012 R2 OS you have downloaded. VMWare recognises the OS version automatically. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNyK8RGp04LWLxkGL9szz4KPCU0B6D6g5BieC0mzTo9pBfx-z2K0rkncDU24_39ItfYbcvklsI6jAp3sJ2mczXrYO2MKRp-r_E5st2KdeSqfsupixg7DqmQgnUK49oQILKjSThEWQcP_sr/s1600/SharePoint+2016+installation+-+marc+charmois+06+-+create+a+new+vmWare+virtual+machine.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNyK8RGp04LWLxkGL9szz4KPCU0B6D6g5BieC0mzTo9pBfx-z2K0rkncDU24_39ItfYbcvklsI6jAp3sJ2mczXrYO2MKRp-r_E5st2KdeSqfsupixg7DqmQgnUK49oQILKjSThEWQcP_sr/s1600/SharePoint+2016+installation+-+marc+charmois+06+-+create+a+new+vmWare+virtual+machine.png"></a><br />
<br />
Then specify the Virtual Machine name and location. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR9FIOO7QwidQxs2BPOFhve8CBd6ehsZP9RdYTMPhLA4XDuqbdUtUkfVb9oflDkrYCEA-2SdLRBnl6WCeD85vBS8uybiNMa8Jjhxqiu1Jv_l2vOncaa2G_52gJl019F7UhEzdR0WOvBgld/s1600/SharePoint+2016+installation+-+marc+charmois+07+-+create+a+new+vmWare+virtual+machine.png" imageanchor="1" ><img border="0" border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR9FIOO7QwidQxs2BPOFhve8CBd6ehsZP9RdYTMPhLA4XDuqbdUtUkfVb9oflDkrYCEA-2SdLRBnl6WCeD85vBS8uybiNMa8Jjhxqiu1Jv_l2vOncaa2G_52gJl019F7UhEzdR0WOvBgld/s1600/SharePoint+2016+installation+-+marc+charmois+07+-+create+a+new+vmWare+virtual+machine.png"></a><br />
<br />
Microsoft recommend 80 Go for the main hard disk. I let the automatic sizing set by VMWare regarding Windows Serve 2012 R2, because, if needed I know I can expand my disk. I chose to store the disk within a single file because it is better in matter of performances.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG5ogyd6YFL9gj31-zir9bgIHS-t9ZtENvAh-4B74-rLBM28bOuXxzYWoV6USc6iqS7ZXo7AjrZnpcrl7Zqh0jBOxjS_8PW2TSDq5dlI_dY9zfK0UFTBHWQAvrmoCOS9zG6YhZHK-6qg00/s1600/SharePoint+2016+installation+-+marc+charmois+08+-+create+a+new+vmWare+virtual+machine.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG5ogyd6YFL9gj31-zir9bgIHS-t9ZtENvAh-4B74-rLBM28bOuXxzYWoV6USc6iqS7ZXo7AjrZnpcrl7Zqh0jBOxjS_8PW2TSDq5dlI_dY9zfK0UFTBHWQAvrmoCOS9zG6YhZHK-6qg00/s1600/SharePoint+2016+installation+-+marc+charmois+08+-+create+a+new+vmWare+virtual+machine.png"></a><br />
<br />
Then, VMWare is summarizing your first settings but you have to add some more regarding the hardware configuration. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg21uUcUSZ-1Rw0Q20C_U30qNzVQmwWW7z65ZuT0WgTaOYqgY6dp0TPEDcEUqTwBbl1PBAqhvc-vF-6zxFrneexFKKDunqVqee49qPC53RYGLnSOZJiWv0GljANC7-HWA-_fX-ompkJFV1-/s1600/SharePoint+2016+installation+-+marc+charmois+09+-+create+a+new+vmWare+virtual+machine+-+first+settings+summarized.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg21uUcUSZ-1Rw0Q20C_U30qNzVQmwWW7z65ZuT0WgTaOYqgY6dp0TPEDcEUqTwBbl1PBAqhvc-vF-6zxFrneexFKKDunqVqee49qPC53RYGLnSOZJiWv0GljANC7-HWA-_fX-ompkJFV1-/s1600/SharePoint+2016+installation+-+marc+charmois+09+-+create+a+new+vmWare+virtual+machine+-+first+settings+summarized.png"></a><br />
<br />
First, start setting the memory as recommended by Microsoft, so at least 8 Go. (Of course it depends also on the amount you have in your Host Machine. Your host machine is your real computer). <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh15Tgpmg5rKBYsgvx6FrRbyultNw5WTJK0xCXOflYSLiDxcDFtHyXe7lG9hkv0IODfMwBwiVsOFCI6lZdEtgWVlnMpbTnb992z2qy6BCwJAyaA6E8SQZFfv5Wx8myd-SvIc1Wpae8-_i2a/s1600/SharePoint+2016+installation+-+marc+charmois+10+-+create+a+new+vmWare+virtual+machine+-+first+settings+summarized.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh15Tgpmg5rKBYsgvx6FrRbyultNw5WTJK0xCXOflYSLiDxcDFtHyXe7lG9hkv0IODfMwBwiVsOFCI6lZdEtgWVlnMpbTnb992z2qy6BCwJAyaA6E8SQZFfv5Wx8myd-SvIc1Wpae8-_i2a/s1600/SharePoint+2016+installation+-+marc+charmois+10+-+create+a+new+vmWare+virtual+machine+-+first+settings+summarized.png"></a><br />
<br />
Choose the same number of processors than in your host machine : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnTQ5Rh3V6gWOAemxlfkLx53graEYDKql3qfhYt0pOYcra865Wc5j1facDXgYb_28VuZjw3qXYQ_mW1AYN8JvI9s6zpDcnVNYX010UIekxHLbAxW3sMiL6fP217tqaXLzRVciVL_fQrGY/s1600/SharePoint+2016+installation+-+marc+charmois+11+-+create+a+new+vmWare+virtual+machine+-+number+of+processors.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnTQ5Rh3V6gWOAemxlfkLx53graEYDKql3qfhYt0pOYcra865Wc5j1facDXgYb_28VuZjw3qXYQ_mW1AYN8JvI9s6zpDcnVNYX010UIekxHLbAxW3sMiL6fP217tqaXLzRVciVL_fQrGY/s1600/SharePoint+2016+installation+-+marc+charmois+11+-+create+a+new+vmWare+virtual+machine+-+number+of+processors.png"></a><br />
<br />
A good way to know the number or Cores is to open the task manager, and in the "Performances" tab, check the number of graphes... I have only one block so I have a mono Core in my host machine. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsEICasI2bdQTGGN8A53t6g43nRcPKax8Ejp120HdsKoghLq9c1-50fTSDzHOFinddrL7nIQhvqtNVddw1XrBUCuesRex0KNmFpu2S4mqN6yTan-DfM9zf-BWi_cTexrb0gyziyOSwwzGv/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+number+of+processors.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsEICasI2bdQTGGN8A53t6g43nRcPKax8Ejp120HdsKoghLq9c1-50fTSDzHOFinddrL7nIQhvqtNVddw1XrBUCuesRex0KNmFpu2S4mqN6yTan-DfM9zf-BWi_cTexrb0gyziyOSwwzGv/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+number+of+processors.png"></a><br />
<br />
Deactivate all the devices you won't use, sound card, printer and so on. You don't need them for a trial or development environment...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbQK4pGZ1lIRAh3r3eZ_qRPUdwNQtEW6xPk0qFGn-mihYOIQtbWqGkawkUFrn21VDf0XKEqbQ8q25CYrO9LFDfkmLu5cH5Fng8NDH_uh0gnMjRpsg0FmPvKqzAwUQUg9pWInnUtfEHXIna/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+disable+sound+card.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbQK4pGZ1lIRAh3r3eZ_qRPUdwNQtEW6xPk0qFGn-mihYOIQtbWqGkawkUFrn21VDf0XKEqbQ8q25CYrO9LFDfkmLu5cH5Fng8NDH_uh0gnMjRpsg0FmPvKqzAwUQUg9pWInnUtfEHXIna/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+disable+sound+card.png"></a><br />
<br />
Then, you can start installation. If you have a message 'You have an incorrect version of driver "vmci.sys"', open the machine .vmx file located in the virtual machine folder, locate the vmci0.present parameter and set it to FALSE. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI_ASro10x_pXCPJ47Pr2lY4REwKnY20f0USyCoBDSHCAlgmk2DHprj3iRd6pTytMXDHtVm4unVwwp3zyf6x2ROI7suULJ5iGxNigxnLJyis3nQq_98YorIuJ5_LiIOWg-vlJFvTDPu4EZ/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+number+of+vmci+problem.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI_ASro10x_pXCPJ47Pr2lY4REwKnY20f0USyCoBDSHCAlgmk2DHprj3iRd6pTytMXDHtVm4unVwwp3zyf6x2ROI7suULJ5iGxNigxnLJyis3nQq_98YorIuJ5_LiIOWg-vlJFvTDPu4EZ/s1600/SharePoint+2016+installation+-+marc+charmois+12+-+create+a+new+vmWare+virtual+machine+-+number+of+vmci+problem.png"></a><br />
<br />
The installation is starting loading the files...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-HvEL6L0OBcp9seEE-uet6CSPDD5ZICnrLDoJdwYvh_iVDNxvvlw-5ySiW4WcSRe8z5CLEu1xjm3HRW0YWeTa2K5j3nsxdZ8kf_DHYYv-HqMol8OmOqCphVdoT_3fv_T0Iyz0SIG9wM9-/s1600/SharePoint+2016+installation+-+marc+charmois+13+-+create+a+new+vmWare+virtual+machine+-+loading+files.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-HvEL6L0OBcp9seEE-uet6CSPDD5ZICnrLDoJdwYvh_iVDNxvvlw-5ySiW4WcSRe8z5CLEu1xjm3HRW0YWeTa2K5j3nsxdZ8kf_DHYYv-HqMol8OmOqCphVdoT_3fv_T0Iyz0SIG9wM9-/s1600/SharePoint+2016+installation+-+marc+charmois+13+-+create+a+new+vmWare+virtual+machine+-+loading+files.png"></a><br />
<br />
Then, you are asked for chosing the langage settings...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDQX7KnAMLXGD2g_FZ7-1lkiQYwiqD-AnDOdZZoayGfpxwzHmFZ-s9zqh5S2T6Qb0boRDhgQ3AkK65tTJPjTEOKzDi54ueC4shUAebnxF18NhH7dMZNdWL8r7GGHer7-x5GelJQoKWuMkp/s1600/SharePoint+2016+installation+-+marc+charmois+13+-+create+a+new+vmWare+virtual+machine+-+settings.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDQX7KnAMLXGD2g_FZ7-1lkiQYwiqD-AnDOdZZoayGfpxwzHmFZ-s9zqh5S2T6Qb0boRDhgQ3AkK65tTJPjTEOKzDi54ueC4shUAebnxF18NhH7dMZNdWL8r7GGHer7-x5GelJQoKWuMkp/s1600/SharePoint+2016+installation+-+marc+charmois+13+-+create+a+new+vmWare+virtual+machine+-+settings.png"></a><br />
<br />
Then you have to choose the type of Windows Server 2012 R2 OS you want... Choose a standard with GUI, and accept the License terms<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4oPb1EDM9N1BXITZ7ad49Oh5VJ_vNyfW1Aivzs3RhZK51XbAcugLlcI3VvnWUU-WFQN5ihBf8wpo3kDO4Jk0i7x7WweUPXlBgmweN4xGBcBOodZ1jYNE6D_owdUW37hc_jpgGlAnST5em/s1600/SharePoint+2016+installation+-+marc+charmois+15+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+os+settings.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4oPb1EDM9N1BXITZ7ad49Oh5VJ_vNyfW1Aivzs3RhZK51XbAcugLlcI3VvnWUU-WFQN5ihBf8wpo3kDO4Jk0i7x7WweUPXlBgmweN4xGBcBOodZ1jYNE6D_owdUW37hc_jpgGlAnST5em/s1600/SharePoint+2016+installation+-+marc+charmois+15+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+os+settings.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC7HRmmQgYr9zP8yQ5skaUrIQHurN6_qO8ABqS6gLyL8Liu4q9-cyFFR2d6ysE3hWjRbYxPhNjXUKyUxck8tKi7tU3PqkB287_HoM6Fa-0Mu1hkMoeyXYedmYvrHa4MklQ6RRECE-T3Ez4/s1600/SharePoint+2016+installation+-+marc+charmois+16+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+os+licence+terms.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC7HRmmQgYr9zP8yQ5skaUrIQHurN6_qO8ABqS6gLyL8Liu4q9-cyFFR2d6ysE3hWjRbYxPhNjXUKyUxck8tKi7tU3PqkB287_HoM6Fa-0Mu1hkMoeyXYedmYvrHa4MklQ6RRECE-T3Ez4/s1600/SharePoint+2016+installation+-+marc+charmois+16+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+os+licence+terms.png"></a><br />
<br />
After that you could choose the drive where install the OS but in our case as there is only one disk, we have no choice...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqAjN68Jei0m2LOy3CPneY_IU6daWIdtyM3ZkfEOdzxmSDXxVUNrwBl02keOZjRlscPDWUTkHpro7HQt84a_7-Fs0b6KMvYyvrJ49hlZKhBpoQWAJ5DW0LR39hQMAlFrMXzzRmJQccnyBW/s1600/SharePoint+2016+installation+-+marc+charmois+17+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+location.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqAjN68Jei0m2LOy3CPneY_IU6daWIdtyM3ZkfEOdzxmSDXxVUNrwBl02keOZjRlscPDWUTkHpro7HQt84a_7-Fs0b6KMvYyvrJ49hlZKhBpoQWAJ5DW0LR39hQMAlFrMXzzRmJQccnyBW/s1600/SharePoint+2016+installation+-+marc+charmois+17+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+location.png"></a><br />
<br />
After having performed all that settings the installation is really starting...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXLfYLhZU3emssLdsdh6t9Hf25gn4uV1ts4tGQemJ52-1bROK9_3YGrnvxAccg2WhjX5AJ1Ikl36-cIHZGKts8v5GK8fUD71oMVyRd9jaEigu37xbaIZ9ixfKrm9YODCjTJYDt7o9rIz51/s1600/SharePoint+2016+installation+-+marc+charmois+17+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installationstarted.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXLfYLhZU3emssLdsdh6t9Hf25gn4uV1ts4tGQemJ52-1bROK9_3YGrnvxAccg2WhjX5AJ1Ikl36-cIHZGKts8v5GK8fUD71oMVyRd9jaEigu37xbaIZ9ixfKrm9YODCjTJYDt7o9rIz51/s1600/SharePoint+2016+installation+-+marc+charmois+17+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installationstarted.png"></a><br />
<br />
It lasts roughly 10 to 20 minutes depending of the capacity of your host machine... Finally you are asked for setting the password for the Administrator account. Note : to do a ctrl Alt Del for a VMWare machine you have first to click on it then type ctr Alt and inser. You can also use the VMWare "Player" menu where this action is available. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iaSSZgfx5lZWQIUdVtS90MwLoqx5HFcqS7iGVQVN6g4nAcNZAzzcGT4bCuvrV4L4roERslzz4GjdH3Iax0f8mQBJsSAgFergOnjdEEWdUCE4pPOI8ujcrD7DIrNYDnIkqgkjSqaauGH4/s1600/SharePoint+2016+installation+-+marc+charmois+19+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+finished.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iaSSZgfx5lZWQIUdVtS90MwLoqx5HFcqS7iGVQVN6g4nAcNZAzzcGT4bCuvrV4L4roERslzz4GjdH3Iax0f8mQBJsSAgFergOnjdEEWdUCE4pPOI8ujcrD7DIrNYDnIkqgkjSqaauGH4/s1600/SharePoint+2016+installation+-+marc+charmois+19+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+finished.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmPpOxnIaDAzx7YpljHf7mCycD5mzEc13kwDvxV-Nv3hTQMmhy5B2dgaOPeERqxB9uvPYFbahITpvQjoAjdwoTdfYeubrdyujWKa1w-t-DkRKIyx7LYwIbavLxsF_9CHeFZnLqOjxieWW_/s1600/SharePoint+2016+installation+-+marc+charmois+19+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+settings.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmPpOxnIaDAzx7YpljHf7mCycD5mzEc13kwDvxV-Nv3hTQMmhy5B2dgaOPeERqxB9uvPYFbahITpvQjoAjdwoTdfYeubrdyujWKa1w-t-DkRKIyx7LYwIbavLxsF_9CHeFZnLqOjxieWW_/s1600/SharePoint+2016+installation+-+marc+charmois+19+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+settings.png"></a><br />
<br />
When your Admin password is set, the system asks you to sign in. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY366sUcIL8RiSGsFrIcTFBuNkoSGcF8W9TXtPLc_CPKjXK2euW8TgklPuA_QtBRAHnwo6FVuvdftB9kOiPn_L5rgWd_rVbexoP5gAwhUfdskrdOKX1gu09lFsEH7oNbHBSf8YB8A836Aq/s1600/SharePoint+2016+installation+-+marc+charmois+20+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+signing.png" imageanchor="1" ><img border="0" class="screenshot-large" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY366sUcIL8RiSGsFrIcTFBuNkoSGcF8W9TXtPLc_CPKjXK2euW8TgklPuA_QtBRAHnwo6FVuvdftB9kOiPn_L5rgWd_rVbexoP5gAwhUfdskrdOKX1gu09lFsEH7oNbHBSf8YB8A836Aq/s1600/SharePoint+2016+installation+-+marc+charmois+20+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+signing.png"></a><br />
<br />
and you finally can reach the machine with Windows Server 2012 R2 installed. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWowFd2Xi4-3EDL68FvEaHbYZvJMpxOhGocAMK99w80vv9gvb7rqDt1gMhaccc1hFwA88ZNwDqJ-N3JZOCyKk-3djAcGXtl01vT2S51RYzL8jZCIWO_WbLXN1EGDL8Xoy8pQSWlQHx1Wsw/s1600/SharePoint+2016+installation+-+marc+charmois+21+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+finished.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWowFd2Xi4-3EDL68FvEaHbYZvJMpxOhGocAMK99w80vv9gvb7rqDt1gMhaccc1hFwA88ZNwDqJ-N3JZOCyKk-3djAcGXtl01vT2S51RYzL8jZCIWO_WbLXN1EGDL8Xoy8pQSWlQHx1Wsw/s1600/SharePoint+2016+installation+-+marc+charmois+21+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+installation+finished.png"></a><br />
<br />
As your virtual machine will host SQL Server and SharePoint, you don't need to join a network, so click "No" to the right screen. So, it is done, you have a virtual machine with Windows server 2012 R2 on it, we just have to install SQL Server 2014 and SharePoint now, but before, let's perform some settings to improve the user experience of this trial or development environment and also preparing the installation of the other softwares (SQL Server 2014 and SharePoint 2016).<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">3 - Configuring the Windows Server 2012 R2 OS</div><div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.1 - Installing VMWare tools </div>VMWare tools gives to the Virtual Machine great features like resizing the virtual machine screen properly to adjust it to the screen fo your host machine and enabling the copy-paste feature from the virtual machine to the host one and vice & versa, so install the tools. <br />
You can start the installation using the "Player" menu. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuWRGrYEfjij6FAjiZ2dtyPia7BzVveEcwCK4YGgR-FypyzEuFgwiebWPw3eoK92ftRPgJwVjLUQJOqMtBZ6wKcO3IxmbBpVtHPFCzs0Xa4d7UzdxiO7gxslGOvqZvy1CZwJywWEWdLPx-/s1600/SharePoint+2016+installation+-+marc+charmois+22+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmwaretools.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuWRGrYEfjij6FAjiZ2dtyPia7BzVveEcwCK4YGgR-FypyzEuFgwiebWPw3eoK92ftRPgJwVjLUQJOqMtBZ6wKcO3IxmbBpVtHPFCzs0Xa4d7UzdxiO7gxslGOvqZvy1CZwJywWEWdLPx-/s1600/SharePoint+2016+installation+-+marc+charmois+22+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmwaretools.png"></a><br />
<br />
Then you have to give to the install program the authorization to run, on the next screens, just click "ok".<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMW8AcS8mB4Ygq5tnnDhX42T1RNkKuv7rc88BS6fh4-u75QTJY15KmQc-SlDyHviTPV1CLsOeSE5qQFNNvzSCaCym8bFWH2weDO5hGD_ZZj-MaOUuLIU1HygFatBAPXe6TzQVziAvV5u8r/s1600/SharePoint+2016+installation+-+marc+charmois+24+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmwaretools.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMW8AcS8mB4Ygq5tnnDhX42T1RNkKuv7rc88BS6fh4-u75QTJY15KmQc-SlDyHviTPV1CLsOeSE5qQFNNvzSCaCym8bFWH2weDO5hGD_ZZj-MaOUuLIU1HygFatBAPXe6TzQVziAvV5u8r/s1600/SharePoint+2016+installation+-+marc+charmois+24+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmwaretools.png"></a><br />
<br />
When the installation is finished you are asked for rebooting the vistual machine, just do it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr-byOAcIvtC0z7_0BjFFkuK3LsdSDqTvHt_O1vOPkFp2IKrpdY9WocU3bnYQlZkVZ6_5DenpVS50P1ouxxuDguGj3JYg-hEhytNUB5585KrgeMDJDR9d4KwQwpVaeQifYIzZxiCNqTN22/s1600/SharePoint+2016+installation+-+marc+charmois+25+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmware+tools+-+instalaltion+finished.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr-byOAcIvtC0z7_0BjFFkuK3LsdSDqTvHt_O1vOPkFp2IKrpdY9WocU3bnYQlZkVZ6_5DenpVS50P1ouxxuDguGj3JYg-hEhytNUB5585KrgeMDJDR9d4KwQwpVaeQifYIzZxiCNqTN22/s1600/SharePoint+2016+installation+-+marc+charmois+25+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+vmware+install+vmware+tools+-+instalaltion+finished.png"></a><br />
<br />
When the machine has restarted just minimize it and maximize it and you will notice that the virtual machine screen is now adjusting automatically to the host machine screen. Morevover, If you use the full-screen feature, you will have an experience as if the Windows Server 2012 R2 has been installed on your host computer! <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJRR4l8G9FVwCH_uJP9_RcgMfGo9UwhK0QZrMeUnt1VWgVvvvkvTAmq-o0B813kPolqITD4hbqW2aR9qLJCvYsbVtytnm8BJ_c4VTGqjfs3lxmqd1EMNZihyphenhyphenfsRa-5FGiGNzPuhHt78Rrs/s1600/SharePoint+2016+installation+-+marc+charmois+26+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+vmware+tools+instalaltion+finished+-+resizing+ok.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJRR4l8G9FVwCH_uJP9_RcgMfGo9UwhK0QZrMeUnt1VWgVvvvkvTAmq-o0B813kPolqITD4hbqW2aR9qLJCvYsbVtytnm8BJ_c4VTGqjfs3lxmqd1EMNZihyphenhyphenfsRa-5FGiGNzPuhHt78Rrs/s1600/SharePoint+2016+installation+-+marc+charmois+26+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+vmware+tools+instalaltion+finished+-+resizing+ok.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.2 - renaming the server</div>As you can notice, the server name is not friendly, so click on it to rename the server<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzBeoCWXYAeMcX-uOEoknpfgLZR5oWT_GTt61UmTGC9G0wiI7el9Z6nVhLvab5FMc7xseMzWjY9YT-PmwmgQCQfcLEQLKSfbo-qVKkuYN6TySZC4_zUL17n-LuscGvcvMe5C_sZZK7WhNa/s1600/SharePoint+2016+installation+-+marc+charmois+30+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzBeoCWXYAeMcX-uOEoknpfgLZR5oWT_GTt61UmTGC9G0wiI7el9Z6nVhLvab5FMc7xseMzWjY9YT-PmwmgQCQfcLEQLKSfbo-qVKkuYN6TySZC4_zUL17n-LuscGvcvMe5C_sZZK7WhNa/s1600/SharePoint+2016+installation+-+marc+charmois+30+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png"></a><br />
<br />
Change the description and the server name (don't use a too long name since it is limited by the BIOS policy)<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82MjKNe6MhWeoSMisQ0hb8nJxmYlXSRvCsp6ZhUWZfC2WxW334YE6Et1H0gFsJCtctm67eoORa3qlyktxec5FyVu-pyx50w-5A8k3ZCPHB1xDWdtYnqLk4V_q0z5mJg_WfG89vZ70VY7D/s1600/SharePoint+2016+installation+-+marc+charmois+31+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82MjKNe6MhWeoSMisQ0hb8nJxmYlXSRvCsp6ZhUWZfC2WxW334YE6Et1H0gFsJCtctm67eoORa3qlyktxec5FyVu-pyx50w-5A8k3ZCPHB1xDWdtYnqLk4V_q0z5mJg_WfG89vZ70VY7D/s1600/SharePoint+2016+installation+-+marc+charmois+31+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png"></a><br />
<br />
When it's done you are warned you will have to restart the server. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyf-rEXr3Dt0wv89q7p82GLF9CzfS5PODgReUvdaKSMVz74w6lUgr_kVtVWz0ShoDBSyV4zf_r8puQy1_y_2lEc_hVgXbnOjZrJuiAxfNlfQGExvXxLlBVmTeMgV_MlcSqZ9xS7apBzDQn/s1600/SharePoint+2016+installation+-+marc+charmois+32+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyf-rEXr3Dt0wv89q7p82GLF9CzfS5PODgReUvdaKSMVz74w6lUgr_kVtVWz0ShoDBSyV4zf_r8puQy1_y_2lEc_hVgXbnOjZrJuiAxfNlfQGExvXxLlBVmTeMgV_MlcSqZ9xS7apBzDQn/s1600/SharePoint+2016+installation+-+marc+charmois+32+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png"></a><br />
<br />
You will asked to "Restart now" when you will have clicked on the "Apply" button of the first modal window. Just do it<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3lHt7iqFKqHf1GXhix9h6UnVCZV3mlKaICrbO7UF3HxkqxcxZk7Nnmubn-WEqUOQGdP8cxyqN0LHc9jvjNmRHketxDh7V3X0F0rKmAYNPH3uHRI6ZaEE0JymtXvVa-rVbm3GYYgo10923/s1600/SharePoint+2016+installation+-+marc+charmois+33+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3lHt7iqFKqHf1GXhix9h6UnVCZV3mlKaICrbO7UF3HxkqxcxZk7Nnmubn-WEqUOQGdP8cxyqN0LHc9jvjNmRHketxDh7V3X0F0rKmAYNPH3uHRI6ZaEE0JymtXvVa-rVbm3GYYgo10923/s1600/SharePoint+2016+installation+-+marc+charmois+33+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+renaming+computer.png"></a><br />
<br />
When your server are restarted you will notice that its name has changed...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlvxaTe-hXIkbnk0pfmwpLcqnZ5Ui9gc0VtsVxHjY9rhT1QVTKesqLEYgJK8-eo8CvZ4fY-rVHi2Kih4qgeEN2miqhdF0yE0nLZ34Ki1Gd5vaWktr2B8AYKtgl42D0zWRs0SWm_1vvOHWf/s1600/SharePoint+2016+installation+-+marc+charmois+34+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+computer+renamed.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlvxaTe-hXIkbnk0pfmwpLcqnZ5Ui9gc0VtsVxHjY9rhT1QVTKesqLEYgJK8-eo8CvZ4fY-rVHi2Kih4qgeEN2miqhdF0yE0nLZ34Ki1Gd5vaWktr2B8AYKtgl42D0zWRs0SWm_1vvOHWf/s1600/SharePoint+2016+installation+-+marc+charmois+34+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+computer+renamed.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.3 - Disabling the Internet Explorer Enhanced Security</div>For a best experience using Internet Explorer disable enhanced security. Locate the link button. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNW2u24GV1di8NCJinBzDyt5vd1p0TxunGA-e0XJ7ZW1V6ch6uQwsdjxbIiLaxqLsrQFfTEahd_KpzTfAir39RvojdRPJxQ0oCLa17vTkZcrZ2Ksn0RIgeaM00_fZttDWXlX-hp6doNiPJ/s1600/SharePoint+2016+installation+-+marc+charmois+27+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNW2u24GV1di8NCJinBzDyt5vd1p0TxunGA-e0XJ7ZW1V6ch6uQwsdjxbIiLaxqLsrQFfTEahd_KpzTfAir39RvojdRPJxQ0oCLa17vTkZcrZ2Ksn0RIgeaM00_fZttDWXlX-hp6doNiPJ/s1600/SharePoint+2016+installation+-+marc+charmois+27+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png"></a><br />
<br />
Set everything to off. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicXFXr6XLMyJL4oXhS_6aqLnRmPWWgxkyKeqbzOt4vvY3Ps1OiGOvbRSAfnjMHmw1ZJcOpidQLRzZH540jIqbcc156SFPkNV1gocCNlsTOEj2_fuj_RQlVY0ckmDSUmC-N2nvWmpPRqg4-/s1600/SharePoint+2016+installation+-+marc+charmois+28+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicXFXr6XLMyJL4oXhS_6aqLnRmPWWgxkyKeqbzOt4vvY3Ps1OiGOvbRSAfnjMHmw1ZJcOpidQLRzZH540jIqbcc156SFPkNV1gocCNlsTOEj2_fuj_RQlVY0ckmDSUmC-N2nvWmpPRqg4-/s1600/SharePoint+2016+installation+-+marc+charmois+28+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png"></a><br />
<br />
When refreshing the dashboard you will notice that IE enhanced security has been set to Off. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKAllrCqSmOmV0Qk3SxPWYjqqesOEu9JjtvPFPw8QkyCikvxmrUi4m8fg7bWAFkep7DGnTVdkIZlnbsz36lFAEE9TU9c2w_zbO8o4pR-Up5j1h3c-ZKfaBG1Rbn11uuAtFyW1tKqdhnlMh/s1600/SharePoint+2016+installation+-+marc+charmois+29+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKAllrCqSmOmV0Qk3SxPWYjqqesOEu9JjtvPFPw8QkyCikvxmrUi4m8fg7bWAFkep7DGnTVdkIZlnbsz36lFAEE9TU9c2w_zbO8o4pR-Up5j1h3c-ZKfaBG1Rbn11uuAtFyW1tKqdhnlMh/s1600/SharePoint+2016+installation+-+marc+charmois+29+-+create+a+new+vmWare+virtual+machine+-+Windows+2k12+Server+-+disable+IE+enhanced+security.png"></a><br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.4 - Disabling the Firewalls</div><br />
Because we use a single virtual machine for trial or development matters, we can disable the firewall. Disabling the Firewalls will improve performances, and, furthermore, we won't have a warning regarding Firewall when installing SQL Server 2014. Thus, navigate to the Server Manager page and locate the "Windows Firewall" link button.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2hmpgWEI7whyphenhyphenRrkwGfjnG3u8N9jVI_NTwjkNdneUK0TcVrWtEUfYpNx9jM5B_wZ3Vg2Qo1_cBu7WY-Nq-FQ4ihezxSzsI8DNTRTXbdPTi_MVssvkRLDvbQ1GAaU2m8V3qJsdzoeVGV-bn/s1600/SharePoint+2016+installation+-+marc+charmois+30+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2hmpgWEI7whyphenhyphenRrkwGfjnG3u8N9jVI_NTwjkNdneUK0TcVrWtEUfYpNx9jM5B_wZ3Vg2Qo1_cBu7WY-Nq-FQ4ihezxSzsI8DNTRTXbdPTi_MVssvkRLDvbQ1GAaU2m8V3qJsdzoeVGV-bn/s1600/SharePoint+2016+installation+-+marc+charmois+30+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png"></a><br />
<br />
Click on it and on the opening pop-up, disable the Firewalls. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfMCKcA1ltJLA12hB71ih040u4t-pKFbe06hvEsz9lDhxO5ok6QUv0PczXV_ugyqALyPLi7H2QI5jVVDD48VA79_wg_ieD5_Xk-aIRjPzVUcDEoAHPkcFP0bkwQy9uAWXTX2i0W7KlkKYF/s1600/SharePoint+2016+installation+-+marc+charmois+32+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfMCKcA1ltJLA12hB71ih040u4t-pKFbe06hvEsz9lDhxO5ok6QUv0PczXV_ugyqALyPLi7H2QI5jVVDD48VA79_wg_ieD5_Xk-aIRjPzVUcDEoAHPkcFP0bkwQy9uAWXTX2i0W7KlkKYF/s1600/SharePoint+2016+installation+-+marc+charmois+32+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png"></a><br />
<br />
You will warn that it is not the recommended configuration, but, just don't care, our environment is for trial or development matters. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4m9DBti0cA9ZjcEczX_IPuigF1JXsLkgS8IIxUMNwakgNXqStZIPWCAwpuaQz3EI9XUk-ChwjbTFL9X6IU0Y-faKtjF2l7hCTBGzMnvrxkz42mmvdh2l-tkYBsh4VIykq4K2yl91CxTZZ/s1600/SharePoint+2016+installation+-+marc+charmois+33+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4m9DBti0cA9ZjcEczX_IPuigF1JXsLkgS8IIxUMNwakgNXqStZIPWCAwpuaQz3EI9XUk-ChwjbTFL9X6IU0Y-faKtjF2l7hCTBGzMnvrxkz42mmvdh2l-tkYBsh4VIykq4K2yl91CxTZZ/s1600/SharePoint+2016+installation+-+marc+charmois+33+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png"></a><br />
<br />
When closing the Firewalls configuration pop-up, you will notice that Firewalls has been deactivated properly. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoPQ40QdBB8qqevu5eejLl3LrzYImJHbZZIaYJzbXHmgxQ1EEliSQLuCC9lRfsswxSJm4bZWOm9qlm2FIjMW8sGjL_Sp289IcunSXvLlekV_pF7Av8-LrjUb7XaSNBcXcouhTHD08aXWzH/s1600/SharePoint+2016+installation+-+marc+charmois+34+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoPQ40QdBB8qqevu5eejLl3LrzYImJHbZZIaYJzbXHmgxQ1EEliSQLuCC9lRfsswxSJm4bZWOm9qlm2FIjMW8sGjL_Sp289IcunSXvLlekV_pF7Av8-LrjUb7XaSNBcXcouhTHD08aXWzH/s1600/SharePoint+2016+installation+-+marc+charmois+34+-+Windows+Server+2012+R2+configuration+-+disbling+firewall.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.5 - Adding the Microsoft .NET Framework 3.5 feature</div>We need .Net Framework 3.5 feature activated on the Server because SQL Server 2014 requires it. Let's activate this feature. Go to the Server Manager Dashboard, and click on "Add Roles or Features"<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnfF1FzdrtEfigu3_tU3X89TT4kcYg83vg_8LwBW9yA2H3qM1t4t-VSuCqvO3xi8nX8XNurt5mm7suttFnduMzRr8ZSty0xnM_w_JZPVw71WEw999Ei1YS2J6ljgsOXUJH5C8UtW0ufZge/s1600/SharePoint+2016+installation+-+marc+charmois+20+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnfF1FzdrtEfigu3_tU3X89TT4kcYg83vg_8LwBW9yA2H3qM1t4t-VSuCqvO3xi8nX8XNurt5mm7suttFnduMzRr8ZSty0xnM_w_JZPVw71WEw999Ei1YS2J6ljgsOXUJH5C8UtW0ufZge/s1600/SharePoint+2016+installation+-+marc+charmois+20+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
Pass the warning screen... and the two next ones<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTMRsK0DIhoA2U16Gd9kjDGiv2fwYD9c1OerrKpYYfQvEnHG2_dgt6bEyynMuai8WOsfqDvOo84n9elwT9KIMAooRGuW_NZTlVw_Gj8jt88CewtNX5y4lNbiQYEmCjQ8grrJqGbRj9jLT0/s1600/SharePoint+2016+installation+-+marc+charmois+21+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTMRsK0DIhoA2U16Gd9kjDGiv2fwYD9c1OerrKpYYfQvEnHG2_dgt6bEyynMuai8WOsfqDvOo84n9elwT9KIMAooRGuW_NZTlVw_Gj8jt88CewtNX5y4lNbiQYEmCjQ8grrJqGbRj9jLT0/s1600/SharePoint+2016+installation+-+marc+charmois+21+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTajTGRxdUXaW6iqlgb1eTAkvXYTRDoYTiIsfGcSszOSEFniwwP1pjuHwpitTe6i1on0sG2-w1ohd7EV1QOAxoIIrFIQpHFAH0IqA1Wsg9Fyha5c0flhAOR9-fFQcFshAN6bffCq0C6_nH/s1600/SharePoint+2016+installation+-+marc+charmois+22+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTajTGRxdUXaW6iqlgb1eTAkvXYTRDoYTiIsfGcSszOSEFniwwP1pjuHwpitTe6i1on0sG2-w1ohd7EV1QOAxoIIrFIQpHFAH0IqA1Wsg9Fyha5c0flhAOR9-fFQcFshAN6bffCq0C6_nH/s1600/SharePoint+2016+installation+-+marc+charmois+22+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyTYat5zRZMAQAce8ifDefCQnd_jdxDz5UcvH0tOenLp6onu8bEkIjEXPYrBU2up0EuEavVMvPn_Ynh14pnK-hZz1lBmdih8y8fxv3IMmJr8ZXAq4xxdsbg_73nhYyMnf9FMYqg7lqOqi1/s1600/SharePoint+2016+installation+-+marc+charmois+23+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyTYat5zRZMAQAce8ifDefCQnd_jdxDz5UcvH0tOenLp6onu8bEkIjEXPYrBU2up0EuEavVMvPn_Ynh14pnK-hZz1lBmdih8y8fxv3IMmJr8ZXAq4xxdsbg_73nhYyMnf9FMYqg7lqOqi1/s1600/SharePoint+2016+installation+-+marc+charmois+23+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
Then, select the Feature menu and check the Framework 3.5 option. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYPQycMqbwc2E8_hCb6p6OGlCaktERLPEajl8sECfSL-6tYsSM76Qf_OSv6n68Z3PQB7uStds-ZqzeRQx0oRHF3oJQGiVILM1daaNp112UB-o2AyGy131OLRYHjncTOV5sK1wSb0ZNA0Af/s1600/SharePoint+2016+installation+-+marc+charmois+24+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYPQycMqbwc2E8_hCb6p6OGlCaktERLPEajl8sECfSL-6tYsSM76Qf_OSv6n68Z3PQB7uStds-ZqzeRQx0oRHF3oJQGiVILM1daaNp112UB-o2AyGy131OLRYHjncTOV5sK1wSb0ZNA0Af/s1600/SharePoint+2016+installation+-+marc+charmois+24+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a> <br />
<br />
Start the activation of this feature...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH5hPq6ae6Ujn6_KRY6J6Mtrmm-g3uHkqitDBVRY4QGKw7fQIcQ6odrJ8Lk8SW0VXxcIN7H0wOE8MLckx8AeiNs974S4nIi1TygoYh3wsHBKCnFDCZWktDdRRAwk7Xsh5WgHxdossrR-UY/s1600/SharePoint+2016+installation+-+marc+charmois+25+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH5hPq6ae6Ujn6_KRY6J6Mtrmm-g3uHkqitDBVRY4QGKw7fQIcQ6odrJ8Lk8SW0VXxcIN7H0wOE8MLckx8AeiNs974S4nIi1TygoYh3wsHBKCnFDCZWktDdRRAwk7Xsh5WgHxdossrR-UY/s1600/SharePoint+2016+installation+-+marc+charmois+25+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXwpsCXcqkamY-Az8A-91E5SV2A8dtGynkxJ5lUVsD4xDPE6Or-w99gbGqyRqFdnBQRVIFJ7gt4tPIZjZHlFN7xJoYQqHKtk_T7gb8eq99vobJ_t9E44HwwHtUueYqV93IXg-StBw2CKaP/s1600/SharePoint+2016+installation+-+marc+charmois+26+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXwpsCXcqkamY-Az8A-91E5SV2A8dtGynkxJ5lUVsD4xDPE6Or-w99gbGqyRqFdnBQRVIFJ7gt4tPIZjZHlFN7xJoYQqHKtk_T7gb8eq99vobJ_t9E44HwwHtUueYqV93IXg-StBw2CKaP/s1600/SharePoint+2016+installation+-+marc+charmois+26+-+Windows+Server+2012+R2+configuration+-+enabling+.Net+3.5.png"></a><br />
<br />
You will obtain this screen when it is complete. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQGHX_OjSeYK3Jv4xlkuxtlSl6gUzUaxVlYHcrlARbWkOPWo7d-Fpz7_a3X8ZqhBzGrF_vZBmznB8N_XenIQyZ-3hsFi60DrYweYpCLLoZiartp7WDBTdTgIfGOqgEWop2VodO1cuej8Z/s1600/SharePoint+2016+installation+-+marc+charmois+27+-+Windows+Server+2012+R2+configuration+-++.Net+3.5+enabled.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQGHX_OjSeYK3Jv4xlkuxtlSl6gUzUaxVlYHcrlARbWkOPWo7d-Fpz7_a3X8ZqhBzGrF_vZBmznB8N_XenIQyZ-3hsFi60DrYweYpCLLoZiartp7WDBTdTgIfGOqgEWop2VodO1cuej8Z/s1600/SharePoint+2016+installation+-+marc+charmois+27+-+Windows+Server+2012+R2+configuration+-++.Net+3.5+enabled.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">3.6 - Installing Microsoft the Service Pack 1 of the .NET Framework 3.5</div><br />
SQL Server 2014 requires this Service Pack. Navigate to the <a href="https://www.microsoft.com/en-US/download/details.aspx?id=22">Microsoft Download Center page for downloading this Service Pack 1</a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_FV_2Dc0h688q-9wf0EUAfwKOY_t-X25XA9DdfKlNxHqCIFUpCjBc9l2IqhY3movDiCXQhCapSsDNizOLc4jzX1oOF_WNq7ogbWLcQMWb87MgOY0ut_XYba326-0fXrUF5fWL195NwuEf/s1600/SharePoint+2016+installation+-+marc+charmois+35+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_FV_2Dc0h688q-9wf0EUAfwKOY_t-X25XA9DdfKlNxHqCIFUpCjBc9l2IqhY3movDiCXQhCapSsDNizOLc4jzX1oOF_WNq7ogbWLcQMWb87MgOY0ut_XYba326-0fXrUF5fWL195NwuEf/s1600/SharePoint+2016+installation+-+marc+charmois+35+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png"></a><br />
<br />
Download the package...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwJ-AB_8WsLK2lGJMeG2rIfG-Cuuyf4iRsltuloAzI-Pp5CGLoS_GdQmqe6f5utK7OP8W1FX5pBV1qRVarTl_nGuLCRZK-QWQlCsLjTs8F1H7SjadIuOgzJV-bJ_jka1W9T2INhT2hhvmx/s1600/SharePoint+2016+installation+-+marc+charmois+36+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwJ-AB_8WsLK2lGJMeG2rIfG-Cuuyf4iRsltuloAzI-Pp5CGLoS_GdQmqe6f5utK7OP8W1FX5pBV1qRVarTl_nGuLCRZK-QWQlCsLjTs8F1H7SjadIuOgzJV-bJ_jka1W9T2INhT2hhvmx/s1600/SharePoint+2016+installation+-+marc+charmois+36+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png"></a><br />
<br />
when it's downloaded run the installation. If it is not running, don't mind, <span style="background-color:yellow">it means that the feature on the server is already complete.</span><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-YZaRjPyCDKkD3l1goBoyYvEWJlLQjXINxACynoNYhMzukaoJxYgH6THzD51PLo6YBblT-Ma4No40Q-XRofRAsx_Fiql7WLix3ncCO2T3Hqe0mWuQjITtujLiUjpT9HiAl5RPiYas7V8M/s1600/SharePoint+2016+installation+-+marc+charmois+37+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-YZaRjPyCDKkD3l1goBoyYvEWJlLQjXINxACynoNYhMzukaoJxYgH6THzD51PLo6YBblT-Ma4No40Q-XRofRAsx_Fiql7WLix3ncCO2T3Hqe0mWuQjITtujLiUjpT9HiAl5RPiYas7V8M/s1600/SharePoint+2016+installation+-+marc+charmois+37+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOoqlfIQnz2vUMc5UeQ6F0UHhQkPk-zEjppR0a2W7liKfffHqA8SsZjf0trdTD3CpYqbnA0TeixiQ2R3zDK2x1jV_sm8DIleu8cn0QbtCOjHjoM2OfvM8wAen5hDWW92iKa1R8iHtflx9j/s1600/SharePoint+2016+installation+-+marc+charmois+38+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOoqlfIQnz2vUMc5UeQ6F0UHhQkPk-zEjppR0a2W7liKfffHqA8SsZjf0trdTD3CpYqbnA0TeixiQ2R3zDK2x1jV_sm8DIleu8cn0QbtCOjHjoM2OfvM8wAen5hDWW92iKa1R8iHtflx9j/s1600/SharePoint+2016+installation+-+marc+charmois+38+-+Windows+Server+2012+R2+configuration+-+installing+.Net+3.5+SP1.png"></a><br />
<br />
We can proceed to the installation of SQL Server 2014<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">4 - Installation of SQL Server 2014 on Windows Server 2012 R2</div><div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">4.1 - Downloading the SQL Server 2014 SP1 180 days evaluation</div><br />
Navigate to the <a href="http://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2014">Technet page to downlod the SQL Server 2014 SP1 180 days evaluation</a>. You will be warned that you have to sign in. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcD_WJ3HvsrEnuo-pggzkj7y08iaGyFKK7ntcucxckEuIsMdlJ9-rfeSIUud6wIZw5m3xm-SMlFWgm410XF992OsUK79CfTAAB4vUD1fNJGCL4JfWEvZJSZUAzhsGWPkvrZRdmN5fv4wEd/s1600/SharePoint+2016+installation+-+marc+charmois+35+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcD_WJ3HvsrEnuo-pggzkj7y08iaGyFKK7ntcucxckEuIsMdlJ9-rfeSIUud6wIZw5m3xm-SMlFWgm410XF992OsUK79CfTAAB4vUD1fNJGCL4JfWEvZJSZUAzhsGWPkvrZRdmN5fv4wEd/s1600/SharePoint+2016+installation+-+marc+charmois+35+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png"></a><br />
<br />
Take care to choose the ISO file<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNw_5Aoyhmz6a5BCIRT9FBoQK3ZE2DNASeXwgdfHpdQDrJiitKrNM3MwDcJs0baAC-C9xXGLZ21-MS-K_POKUzJUMwBCj7ITASh_XOCVXyCh6dS2ehf2vW9UvvcXuQXiiYjPhyphenhyphentvhyIGIQ/s1600/SharePoint+2016+installation+-+marc+charmois+36+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png" imageanchor="1" ><img border="0" class="screenshot-standard" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNw_5Aoyhmz6a5BCIRT9FBoQK3ZE2DNASeXwgdfHpdQDrJiitKrNM3MwDcJs0baAC-C9xXGLZ21-MS-K_POKUzJUMwBCj7ITASh_XOCVXyCh6dS2ehf2vW9UvvcXuQXiiYjPhyphenhyphentvhyIGIQ/s1600/SharePoint+2016+installation+-+marc+charmois+36+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png"></a><br />
<br />
and the 64bit type version of SQL Server 2014 + SP1<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjddSaHIeOjqzuhV-7ksSfNNsXi35WgyET59XhWTdnfzBC59AUD7tGM7RFuujD6WLouO6kdFhs2hmGLbQdNIzSv3OqUBvtfZpcI20_jOPguqIL5X1ts45Hf78887WpNCyUL_4byT2GyspD/s1600/SharePoint+2016+installation+-+marc+charmois+37+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjddSaHIeOjqzuhV-7ksSfNNsXi35WgyET59XhWTdnfzBC59AUD7tGM7RFuujD6WLouO6kdFhs2hmGLbQdNIzSv3OqUBvtfZpcI20_jOPguqIL5X1ts45Hf78887WpNCyUL_4byT2GyspD/s1600/SharePoint+2016+installation+-+marc+charmois+37+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png"></a><br />
<br />
For a matter of testing, it is always better to choose the English products...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsHn09DyWfFQiGSwWvyJGnZNH93jsTignuNdO084HO1EmdojsdxLtHwd9LVD31ESMoWcKpFZmojD2WHUw9tfGGxNJXUfFhhjXpo11dFz1fbSE3sBY9DSS0IuOS6enL-oPaZFxgMJKdqWIm/s1600/SharePoint+2016+installation+-+marc+charmois+38+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsHn09DyWfFQiGSwWvyJGnZNH93jsTignuNdO084HO1EmdojsdxLtHwd9LVD31ESMoWcKpFZmojD2WHUw9tfGGxNJXUfFhhjXpo11dFz1fbSE3sBY9DSS0IuOS6enL-oPaZFxgMJKdqWIm/s1600/SharePoint+2016+installation+-+marc+charmois+38+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png"></a><br />
<br />
Then you finally can proceed to the download...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipFau30TVxTjp5Ngm90nMHzZyrm9q6PLbYsdgQVVfP_CZKeYK8RldHO1lBFWJLPszTWf1yiFFDDuUL9-6wUBuB4tVeYYz0knycDzlIeduMLnPFDum-i3nV24MMo-C3_bcXssdvuD-oNAsu/s1600/SharePoint+2016+installation+-+marc+charmois+39+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipFau30TVxTjp5Ngm90nMHzZyrm9q6PLbYsdgQVVfP_CZKeYK8RldHO1lBFWJLPszTWf1yiFFDDuUL9-6wUBuB4tVeYYz0knycDzlIeduMLnPFDum-i3nV24MMo-C3_bcXssdvuD-oNAsu/s1600/SharePoint+2016+installation+-+marc+charmois+39+-+SQL+Server+2014+installation+-+downlaoding+180+days+evalutaion.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">4.2 - Mounting the .iso image of the SQL Server 2014 SP1 on the Windows Server 2012 R2 virtual machine</div>When your .iso file is downloaded, mount it as the d:\ drive of your virtual machine. Start navigating to the CD settings via the "Player" menu; <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnqcgyqjru-OxFzTEjElSKX7MhGq8XRVIIn5tXF2Bb9mi7yTJss6eHvXzWbztQelWp9iPjCkPNbgCjP-oTGkgTghoFxlQhRuyrspGXamZ_jYUfn_I4zw2tjZGMHWy7WRIpaIfqm8ZYli7y/s1600/SharePoint+2016+installation+-+marc+charmois+40+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnqcgyqjru-OxFzTEjElSKX7MhGq8XRVIIn5tXF2Bb9mi7yTJss6eHvXzWbztQelWp9iPjCkPNbgCjP-oTGkgTghoFxlQhRuyrspGXamZ_jYUfn_I4zw2tjZGMHWy7WRIpaIfqm8ZYli7y/s1600/SharePoint+2016+installation+-+marc+charmois+40+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png"></a><br />
<br />
then, browse for the SQL Server 2014 installation .iso file<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivbXZ9OX31Jlv_TV6_uAILlZ3eFZ5jweMHnsehpeMyoUkQ_lTi9gXkwrfx-GkC1W_7NIRy9ZyLcNxd5q1aN_Ae9laklB9z105Bg5WOEHRw4WCAo6U2dpRVyYHbYpcZWDlaBEl-AZdWFey_/s1600/SharePoint+2016+installation+-+marc+charmois+41+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivbXZ9OX31Jlv_TV6_uAILlZ3eFZ5jweMHnsehpeMyoUkQ_lTi9gXkwrfx-GkC1W_7NIRy9ZyLcNxd5q1aN_Ae9laklB9z105Bg5WOEHRw4WCAo6U2dpRVyYHbYpcZWDlaBEl-AZdWFey_/s1600/SharePoint+2016+installation+-+marc+charmois+41+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png"></a><br />
<br />
When the .iso image is mounted click the Windows Server 2012 R2 start button. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvYfOrjWUtg7Rz244pLuURzIl26f4cGA0rdJ3A1UhdfcskRXpfWDtYaTAMzBJvwQ2scWCWHI_4X4Dbkod1WrS-po7FTGPDGT9INhFyqWGd9-Nv0ixc4s9JLzjyKO3Kx4ie9GHTCqtkGmL5/s1600/SharePoint+2016+installation+-+marc+charmois+42+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvYfOrjWUtg7Rz244pLuURzIl26f4cGA0rdJ3A1UhdfcskRXpfWDtYaTAMzBJvwQ2scWCWHI_4X4Dbkod1WrS-po7FTGPDGT9INhFyqWGd9-Nv0ixc4s9JLzjyKO3Kx4ie9GHTCqtkGmL5/s1600/SharePoint+2016+installation+-+marc+charmois+42+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png"></a><br />
<br />
Then, locate the "This PC" button and click on it.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1403Rp60185qbAVdgh7ztY28F-s30I7X0WAzrAzJ7P8kf38xBJuz9EG6xgKzvjNBPJEy7DR-rYLe9d5WNMekjk4Gb_mBjM2OIwke65JuZpoL5CNpB4RjoLkhyphenhyphenJO6nyDk-Aj4kRkXYpT3D/s1600/SharePoint+2016+installation+-+marc+charmois+43+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1403Rp60185qbAVdgh7ztY28F-s30I7X0WAzrAzJ7P8kf38xBJuz9EG6xgKzvjNBPJEy7DR-rYLe9d5WNMekjk4Gb_mBjM2OIwke65JuZpoL5CNpB4RjoLkhyphenhyphenJO6nyDk-Aj4kRkXYpT3D/s1600/SharePoint+2016+installation+-+marc+charmois+43+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png"></a><br />
<br />
You can see that the .iso image of the SQL Server 2014 + SP1 has been properly mounted. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc35XiyNjl066KwjjAjmhXmxYX37kDTx5pqqVp8kZMc5CPeeWzem-Q_ciSU03n3S1m9ci8CXPkfs52AyJkeq22k3ecUuCj09l1h2MP4Xyvq9yu14a5aUWA2MtanYPXIFqDEZYKm-pIQtca/s1600/SharePoint+2016+installation+-+marc+charmois+44+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc35XiyNjl066KwjjAjmhXmxYX37kDTx5pqqVp8kZMc5CPeeWzem-Q_ciSU03n3S1m9ci8CXPkfs52AyJkeq22k3ecUuCj09l1h2MP4Xyvq9yu14a5aUWA2MtanYPXIFqDEZYKm-pIQtca/s1600/SharePoint+2016+installation+-+marc+charmois+44+-+SQL+Server+2014+installation+-+mounting+the+.iso+file.png"></a><br />
<br />
We are now ready to install SQL Server 2014 + SP1<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">4.3 - Installing SQL Server 2014 SP1 on Windows Server 2012 R2</div><br />
So, double-click on the SQL Server 2014 .iso image. The SQL Server 2014 installation wizard is launched. Then click on the installation menu item<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqw9d6kJMR2dqCjh2yC8ptrwcd649hWFSTNcbbyZOLnYBRvyQo-sHJEFRX_jWcfCwY-ozJdmyrcvz76r2ppMlqU23OFceffif-BfXew1Jj9P9reAmSkB3zUz7T4cp7G4sO_atBh11n_U_o/s1600/SharePoint+2016+installation+-+marc+charmois+45+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqw9d6kJMR2dqCjh2yC8ptrwcd649hWFSTNcbbyZOLnYBRvyQo-sHJEFRX_jWcfCwY-ozJdmyrcvz76r2ppMlqU23OFceffif-BfXew1Jj9P9reAmSkB3zUz7T4cp7G4sO_atBh11n_U_o/s1600/SharePoint+2016+installation+-+marc+charmois+45+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
And the first item of the new screen : New SQL Server stand-alone installation...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQKhamJRblRnGvN4Blahzel2sPlyitT00PFtl-Zw-e4zJRK36wk9aeRU2sdjLoPbhS5SEY9GNjTSUdAgQludcJ5RXQtngkwz0JUd3FJXhzH8IcO0yjuEsMPj3eFsxvJsKuAQ7D4V1MRND7/s1600/SharePoint+2016+installation+-+marc+charmois+46+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQKhamJRblRnGvN4Blahzel2sPlyitT00PFtl-Zw-e4zJRK36wk9aeRU2sdjLoPbhS5SEY9GNjTSUdAgQludcJ5RXQtngkwz0JUd3FJXhzH8IcO0yjuEsMPj3eFsxvJsKuAQ7D4V1MRND7/s1600/SharePoint+2016+installation+-+marc+charmois+46+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Pass the license screen since we use an evaluation version<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTSDTET8-a-EkKZVB2-Ymcn6QekqJLRPWgXPbiMrD9qVdxUFrcefJFo0Sa3YqRYMr9vr1CKXv0MnGlCLaiqqP-t2qq-NoAasgEvtjI1Mlp0Q7LX7lBb0opsAATeom0a8UDFGOxwvdX4UF9/s1600/SharePoint+2016+installation+-+marc+charmois+47+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTSDTET8-a-EkKZVB2-Ymcn6QekqJLRPWgXPbiMrD9qVdxUFrcefJFo0Sa3YqRYMr9vr1CKXv0MnGlCLaiqqP-t2qq-NoAasgEvtjI1Mlp0Q7LX7lBb0opsAATeom0a8UDFGOxwvdX4UF9/s1600/SharePoint+2016+installation+-+marc+charmois+47+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
and the license terms...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdMXaeVOoGgPWkqArSVDAyoOD_aUzSpYZzv-kSxH1dA1bXtBAkeo4_OTfhtOocqpwI-CBlM4NLBX8Hi18NkkYeVyiZ_OKvC7hRpzRRq4vcC4iJaKH9scFiFM8yghqSIXBOiHrshYnsYt3p/s1600/SharePoint+2016+installation+-+marc+charmois+48+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdMXaeVOoGgPWkqArSVDAyoOD_aUzSpYZzv-kSxH1dA1bXtBAkeo4_OTfhtOocqpwI-CBlM4NLBX8Hi18NkkYeVyiZ_OKvC7hRpzRRq4vcC4iJaKH9scFiFM8yghqSIXBOiHrshYnsYt3p/s1600/SharePoint+2016+installation+-+marc+charmois+48+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Then enable the automatic checking for updates...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL2Y5St_Q9VheoZ1GC8qFUIxR5DaV1Dunrc7GSSiH9f5hMD-uvP9EZbUoStfffzSCUjcvgomzYRvuySxhOaPuz2mwQCsC7wpV5JFufOKkLJlz5zDDHwQfplQvoXv_UWl6niZOUSKuYqXga/s1600/SharePoint+2016+installation+-+marc+charmois+49+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL2Y5St_Q9VheoZ1GC8qFUIxR5DaV1Dunrc7GSSiH9f5hMD-uvP9EZbUoStfffzSCUjcvgomzYRvuySxhOaPuz2mwQCsC7wpV5JFufOKkLJlz5zDDHwQfplQvoXv_UWl6niZOUSKuYqXga/s1600/SharePoint+2016+installation+-+marc+charmois+49+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Check that the first rules are passed<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMd1MlqRgYnKXwhLl8RYv_m6Che14E60ccZ507No-L3u1yI5txImcpkcCeDREg5uk7qILCbc3-lJ6gaWrRI7QtJfBxd7m1OdX5yPfY_vxxf7y3B0u3EgyHbdIsgH1JROUkm-WJH7QRzJXT/s1600/SharePoint+2016+installation+-+marc+charmois+50+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMd1MlqRgYnKXwhLl8RYv_m6Che14E60ccZ507No-L3u1yI5txImcpkcCeDREg5uk7qILCbc3-lJ6gaWrRI7QtJfBxd7m1OdX5yPfY_vxxf7y3B0u3EgyHbdIsgH1JROUkm-WJH7QRzJXT/s1600/SharePoint+2016+installation+-+marc+charmois+50+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Let the first option checked for the next screen <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpHqUH3Q3ApwSkEeAzi8oIC2BcmcC8Qfhjc2wITg_r4x4AJ_59WFNiRybqsNpiiXlMGk_Y62el0fzykxSAgBBNlXXxVsyiCbl1RA2qCuIWOfyydJqT9LuvFDrMY7KKIbZ0X48ZB_3LJCty/s1600/SharePoint+2016+installation+-+marc+charmois+51+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpHqUH3Q3ApwSkEeAzi8oIC2BcmcC8Qfhjc2wITg_r4x4AJ_59WFNiRybqsNpiiXlMGk_Y62el0fzykxSAgBBNlXXxVsyiCbl1RA2qCuIWOfyydJqT9LuvFDrMY7KKIbZ0X48ZB_3LJCty/s1600/SharePoint+2016+installation+-+marc+charmois+51+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Regarding the features, for SharePoint, you only need two : Database Engine Service and Management Tools - Basic<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIPXHovyN_6SshaFzqHOvwiQp0yEaBbByG5x7C5wO5jOdgg1_JIIz6g3Y3GDA7jZdchqUKCqea03abT6uwesUpvIRrCy9o5puj6Kn_2dkDJcLLfiLSOi2en4Kqz6SX8zNtvM3-5Anchx0C/s1600/SharePoint+2016+installation+-+marc+charmois+52+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIPXHovyN_6SshaFzqHOvwiQp0yEaBbByG5x7C5wO5jOdgg1_JIIz6g3Y3GDA7jZdchqUKCqea03abT6uwesUpvIRrCy9o5puj6Kn_2dkDJcLLfiLSOi2en4Kqz6SX8zNtvM3-5Anchx0C/s1600/SharePoint+2016+installation+-+marc+charmois+52+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp1wKGEMXZAbEtNscc24F8dhdraBEvJXJg9GjC1n32Q8UxodJ4qAyN1GBcxUbnGMhvSmugsLsIWrnadDNR3uOy5Hh9t7mziX1ZcxPYXShVXk7xIoLIezWaKqCOqlwNu9S4YMNlIW-tVq8Y/s1600/SharePoint+2016+installation+-+marc+charmois+53+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp1wKGEMXZAbEtNscc24F8dhdraBEvJXJg9GjC1n32Q8UxodJ4qAyN1GBcxUbnGMhvSmugsLsIWrnadDNR3uOy5Hh9t7mziX1ZcxPYXShVXk7xIoLIezWaKqCOqlwNu9S4YMNlIW-tVq8Y/s1600/SharePoint+2016+installation+-+marc+charmois+53+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Pass the Feature Rules<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl0aPfaFt6iBcNR4vWd8Ha2xjQniweJl1YjIq3mt6kJ5aYGSO9gHBXkfVnzyhZgXY8JuBM_vlpjihxGtc4jgQCCMDksApkRPjm8tLBgwh_9y-r9yuj8bVmkyjOYXdG8awW4fOWRRCLDV14/s1600/SharePoint+2016+installation+-+marc+charmois+54+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl0aPfaFt6iBcNR4vWd8Ha2xjQniweJl1YjIq3mt6kJ5aYGSO9gHBXkfVnzyhZgXY8JuBM_vlpjihxGtc4jgQCCMDksApkRPjm8tLBgwh_9y-r9yuj8bVmkyjOYXdG8awW4fOWRRCLDV14/s1600/SharePoint+2016+installation+-+marc+charmois+54+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Let the default option for the next screen. Don't use a named instance because it will be more complicated to install SharePoint with a named instance. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQbOUCKi45kfxfS0DRY0-qac3yiLA4rW9rHxMS23QUM2lm8VdVkBTZKEXHuj_iFixkoiaXDtPaWxX9lf5QQYg7AZYEHcJDcvlFmTf2kQvzr1ZSe98MZLcIzYOirnQahlqTc-PNAF5VwoD4/s1600/SharePoint+2016+installation+-+marc+charmois+55+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQbOUCKi45kfxfS0DRY0-qac3yiLA4rW9rHxMS23QUM2lm8VdVkBTZKEXHuj_iFixkoiaXDtPaWxX9lf5QQYg7AZYEHcJDcvlFmTf2kQvzr1ZSe98MZLcIzYOirnQahlqTc-PNAF5VwoD4/s1600/SharePoint+2016+installation+-+marc+charmois+55+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Let the automatic service account settings<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrmOzn7jMjl8f0yoqMk1dD_5151KnI0ODIYd-qwFWBoGBCc99H4oREfI_x1_eCDVtMnuk5litwrqGtI1K71E0coK7TIR0zQLWfvcigwwLOVAZ13GRG5tqg3HUDegl2wBZrtXsnLbcD8-s/s1600/SharePoint+2016+installation+-+marc+charmois+56+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrmOzn7jMjl8f0yoqMk1dD_5151KnI0ODIYd-qwFWBoGBCc99H4oREfI_x1_eCDVtMnuk5litwrqGtI1K71E0coK7TIR0zQLWfvcigwwLOVAZ13GRG5tqg3HUDegl2wBZrtXsnLbcD8-s/s1600/SharePoint+2016+installation+-+marc+charmois+56+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Enable Mixed mode that allows you to use the "sa" account to connect. Set a complex password, like P@ssw0rd, if not you won't be able to pass this screeen. It is very useful sometimes to have this account in case of connection problem to SQL Server. Use the administrator account of the machine to be the administrator account of SQL.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCrNkCVW8ftrVnszg7puguCM3XR3-gfBuJwEAWb-I8H3kUiQ0uNjiFW34uuA9W5fRdsIv90LPouMcz4hyphenhyphenRvYvUShrNOEElWNt1gXRvLRWMIpKh4zWLgIxpfqJJmWGHDercdBABF1e03DLO/s1600/SharePoint+2016+installation+-+marc+charmois+57+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCrNkCVW8ftrVnszg7puguCM3XR3-gfBuJwEAWb-I8H3kUiQ0uNjiFW34uuA9W5fRdsIv90LPouMcz4hyphenhyphenRvYvUShrNOEElWNt1gXRvLRWMIpKh4zWLgIxpfqJJmWGHDercdBABF1e03DLO/s1600/SharePoint+2016+installation+-+marc+charmois+57+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
SQL intallation wizard, then, summarizes your choices...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixkl4bbruKIXiwVAwgsKJwAiLk0D7bZ4kfjza37VgUpDm74KETnjNBpSSsfzDdqCPkHobuYVH47kvIOxQnaICm88UaQRyGI-AB0EnmifGJbeu-Sfun9p5O4Lo89Lnm_ssacSZisZz3or7L/s1600/SharePoint+2016+installation+-+marc+charmois+58+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixkl4bbruKIXiwVAwgsKJwAiLk0D7bZ4kfjza37VgUpDm74KETnjNBpSSsfzDdqCPkHobuYVH47kvIOxQnaICm88UaQRyGI-AB0EnmifGJbeu-Sfun9p5O4Lo89Lnm_ssacSZisZz3or7L/s1600/SharePoint+2016+installation+-+marc+charmois+58+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
Then, launch the installation...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj60DXnQ8oEjQuCYk95xQmwNIDJflvhNvAPAkUPUDVFItPokVJ0Ugw30oX6NBBno4aHsYPKoQPMqeNlriRs3b8pwRH6keILOt-7LT8SV5XqGjoj83q6egRnUcaaS7m6IsHJrU9HrV4cvvCx/s1600/SharePoint+2016+installation+-+marc+charmois+59+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj60DXnQ8oEjQuCYk95xQmwNIDJflvhNvAPAkUPUDVFItPokVJ0Ugw30oX6NBBno4aHsYPKoQPMqeNlriRs3b8pwRH6keILOt-7LT8SV5XqGjoj83q6egRnUcaaS7m6IsHJrU9HrV4cvvCx/s1600/SharePoint+2016+installation+-+marc+charmois+59+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
You should obtain this screen when installation is complete : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHNVI_Fnj-Z-Tjycc96KK-mn4Hpw6yzZjeIDUMCZXoo5UAy0rHChNCnzGsJzKuhLz-Nalu8yM2xOJf5qkU0RYg96fLBErNL7WhKnpqJt3iBWjsFcws4o6WvIz1wKzXZFmzyOcdmZR7eyfx/s1600/SharePoint+2016+installation+-+marc+charmois+60+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHNVI_Fnj-Z-Tjycc96KK-mn4Hpw6yzZjeIDUMCZXoo5UAy0rHChNCnzGsJzKuhLz-Nalu8yM2xOJf5qkU0RYg96fLBErNL7WhKnpqJt3iBWjsFcws4o6WvIz1wKzXZFmzyOcdmZR7eyfx/s1600/SharePoint+2016+installation+-+marc+charmois+60+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">4.4 - Checking the Installation of SQL Server 2014 SP1 on Windows Server 2012 R2</div><br />
We are now going to check if SQL Server has been installed properly. Click the Window Start button and when arriving in the Start Screen don't click anything, just type "SQL Server" on your keyboard. You will notice that the search input zone took your request automatically. At the bottom of the search results, you will see the SQL Server 2014 Managment Studio link. Click on it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxc_2bV03u6o9hyzBfAJzrGZfNwGysFYMxsrG7F3cce1eTk_LdqF4nOM_uW4xm5oDO9nlixoRCZq0-NTM4L2A8VewWUf6LJDtbGDAG0_ERhg8Dm7QhT3j1C_0bOHmjhQN9V39aQeqI95g/s1600/SharePoint+2016+installation+-+marc+charmois+61+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxc_2bV03u6o9hyzBfAJzrGZfNwGysFYMxsrG7F3cce1eTk_LdqF4nOM_uW4xm5oDO9nlixoRCZq0-NTM4L2A8VewWUf6LJDtbGDAG0_ERhg8Dm7QhT3j1C_0bOHmjhQN9V39aQeqI95g/s1600/SharePoint+2016+installation+-+marc+charmois+61+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
SQL Server 2014 Management Studio is openning...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqWwKzutgtd7a_xPO7pnHQPAFypQaQWD__rnluEAyxOv8ZxX0GvCzdt_3H9D3FONXX68eEHjXqtbCPwP1JpMIeeAfft85vI9THjnqsCnN6Sk5qU1U0aq9DRL1EmUDoMJLSvt3dOJfQoKr7/s1600/SharePoint+2016+installation+-+marc+charmois+62+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqWwKzutgtd7a_xPO7pnHQPAFypQaQWD__rnluEAyxOv8ZxX0GvCzdt_3H9D3FONXX68eEHjXqtbCPwP1JpMIeeAfft85vI9THjnqsCnN6Sk5qU1U0aq9DRL1EmUDoMJLSvt3dOJfQoKr7/s1600/SharePoint+2016+installation+-+marc+charmois+62+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
All the connection parameters are automatically detected... So you just have to click to connect...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieq2lpXh_LNw14B3M_1U0mq_tG7g0FJl-NzQI9EnZTuv8303iIJf-uedYICt8IcIUqL_b7iifQIPIA-DfaQWnli__ea5g6GgayYbezFnDXAYHy9JLKgV-dmTNjeaR_VRmNszao-k0F7Ie5/s1600/SharePoint+2016+installation+-+marc+charmois+63+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieq2lpXh_LNw14B3M_1U0mq_tG7g0FJl-NzQI9EnZTuv8303iIJf-uedYICt8IcIUqL_b7iifQIPIA-DfaQWnli__ea5g6GgayYbezFnDXAYHy9JLKgV-dmTNjeaR_VRmNszao-k0F7Ie5/s1600/SharePoint+2016+installation+-+marc+charmois+63+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
You, then, can check that the SQL 2014 Database Engine is working properly, and that you are able to see the Masters databases: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ_C7W3uCUmfnVJ1KyatVgTZ9eH-WESbHHWLPj9-WWj7cTBV28w4lBsilpGBDLTy0KgbYrmdW2QwQvI-17_yWU-GVH_qS4BIGijMptelk8zVTxqox7GD-rYL-iygmRQEaSz32MG89c5Iyx/s1600/SharePoint+2016+installation+-+marc+charmois+64+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ_C7W3uCUmfnVJ1KyatVgTZ9eH-WESbHHWLPj9-WWj7cTBV28w4lBsilpGBDLTy0KgbYrmdW2QwQvI-17_yWU-GVH_qS4BIGijMptelk8zVTxqox7GD-rYL-iygmRQEaSz32MG89c5Iyx/s1600/SharePoint+2016+installation+-+marc+charmois+64+-+SQL+Server+2014+installation+-+Installing+SQL+Server+2014.png"></a><br />
<br />
We are now finally able to install SharePoint 2016<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">5 - Installing SharePoint 2016 on Windows Server 2012 R2</div><div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">5.1 - Downloading and mounting the .iso image of SharePoint 2016</div><br />
First, here is the link to <a href="https://www.microsoft.com/en-us/download/details.aspx?id=48712">download the SharePoint 2016 preview</a>... Start downloading the package on your host machine (your real computer)...<br />
<span style="background-color:yellow">Don't close the download page because there is the product key of the SharePoint 2016 evaluation on it, or take care to back-up the product key before closing the page.</span><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd4OfdJJdDQ-sDaaCCvhl8ngsZNZK3ea-NzgkkBi01LIiCdENgN1q5wWgXR18WCHqOGCL8nk2pbmRNH83YO41JoYO-xc_GOBU6a2sPEMbMfpZmrSKSyRvQAKZcOyU6E3W84nGFhzSvAp2-/s1600/SharePoint+2016+installation+-+marc+charmois+65+-+SharePoint+2016+installation+-+downloading+the+package.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd4OfdJJdDQ-sDaaCCvhl8ngsZNZK3ea-NzgkkBi01LIiCdENgN1q5wWgXR18WCHqOGCL8nk2pbmRNH83YO41JoYO-xc_GOBU6a2sPEMbMfpZmrSKSyRvQAKZcOyU6E3W84nGFhzSvAp2-/s1600/SharePoint+2016+installation+-+marc+charmois+65+-+SharePoint+2016+installation+-+downloading+the+package.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiat0qjiOeEIixappnuxspIFc1TRtc_tJ0REfI7NAdRDhMpQdBFWmTlnIhLR9xpOi1C5tVF7_X_hsmMPxQp7d4xva3XPOjC4mlPH8_obs6fyxOG0J3rGoX1dOnHs51h3Ju2l61j7IFKn6B6/s1600/SharePoint+2016+installation+-+marc+charmois+65+-+SharePoint+2016+installation+-+iso+file+downloaded.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiat0qjiOeEIixappnuxspIFc1TRtc_tJ0REfI7NAdRDhMpQdBFWmTlnIhLR9xpOi1C5tVF7_X_hsmMPxQp7d4xva3XPOjC4mlPH8_obs6fyxOG0J3rGoX1dOnHs51h3Ju2l61j7IFKn6B6/s1600/SharePoint+2016+installation+-+marc+charmois+65+-+SharePoint+2016+installation+-+iso+file+downloaded.png"></a><br />
<br />
When it's done, mount the .iso image just as we did for the SQL 2014 Server .iso image previously:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTpApwPQc8gaRsxo6QVIw3I582NpWpUxCKLedo975BnYwMaHwQsLUjNOcmYnQ-IDXiB1tt_A7SvymqBKOBRdZ-g1ttDJyu1SKm-Y5w7QUMa-IHGJfFu-e28ZuRkmNgHge-HT_NytZudQFK/s1600/SharePoint+2016+installation+-+marc+charmois+66+-+SharePoint+2016+installation+-+iso+file+downloaded.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTpApwPQc8gaRsxo6QVIw3I582NpWpUxCKLedo975BnYwMaHwQsLUjNOcmYnQ-IDXiB1tt_A7SvymqBKOBRdZ-g1ttDJyu1SKm-Y5w7QUMa-IHGJfFu-e28ZuRkmNgHge-HT_NytZudQFK/s1600/SharePoint+2016+installation+-+marc+charmois+66+-+SharePoint+2016+installation+-+iso+file+downloaded.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AhNGHIKj5sMdljIfRsH7ZMOTTOvwUV9CVHR6B3ng_mEYBQpmxr7TGUfPFBdqUa1SsDpUbv6JoqWLZTXDYAlGQHbhGWDxd3oNgJARJ-e8QmcW1xVYMYeqE3iDI_m4mwOCiIfI3JE0PE0k/s1600/SharePoint+2016+installation+-+marc+charmois+68+-+SharePoint+2016+installation+-+mounting+the+iso+file.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AhNGHIKj5sMdljIfRsH7ZMOTTOvwUV9CVHR6B3ng_mEYBQpmxr7TGUfPFBdqUa1SsDpUbv6JoqWLZTXDYAlGQHbhGWDxd3oNgJARJ-e8QmcW1xVYMYeqE3iDI_m4mwOCiIfI3JE0PE0k/s1600/SharePoint+2016+installation+-+marc+charmois+68+-+SharePoint+2016+installation+-+mounting+the+iso+file.png"></a><br />
<br />
Using the start menu, access to the "This PC" folder and locate the mounted .iso image for the installation of SharePoint 2016, and double click it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWnpPyjdKUOkOGITFCr2-tPVfOjfQ7qWmmbEL9e7HP6n5OxGnAnxU_WXEN0Zh-Kqt6nGyP9CapRsy1KW3TYDyalnaheHAkSbSwnVbRKnBYukY-dnwvUzj37MmjqS9oyXjERg89eHHaWHUu/s1600/SharePoint+2016+installation+-+marc+charmois+68+-+SharePoint+2016+installation+-++iso+file+mounted.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWnpPyjdKUOkOGITFCr2-tPVfOjfQ7qWmmbEL9e7HP6n5OxGnAnxU_WXEN0Zh-Kqt6nGyP9CapRsy1KW3TYDyalnaheHAkSbSwnVbRKnBYukY-dnwvUzj37MmjqS9oyXjERg89eHHaWHUu/s1600/SharePoint+2016+installation+-+marc+charmois+68+-+SharePoint+2016+installation+-++iso+file+mounted.png"></a><br />
<br />
Choose the HTA option for opening the SharePoint 2016 installation menu<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEiVN_JRQqThmaqpRB2FYITrD5-ovVYElkonHIvyugzhCG0rtIB-nEGQ16mTNfm-n0iwXnzpnexvxxm0wPgNMn6tfZAei5xW0PxGNKMi5KexTtonWRxo0kC8Dh_vFfF52caZwt5Cm3kr5/s1600/SharePoint+2016+installation+-+marc+charmois+70+-+SharePoint+2016+installation+-+starting+sharepoint+2016+installation.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEiVN_JRQqThmaqpRB2FYITrD5-ovVYElkonHIvyugzhCG0rtIB-nEGQ16mTNfm-n0iwXnzpnexvxxm0wPgNMn6tfZAei5xW0PxGNKMi5KexTtonWRxo0kC8Dh_vFfF52caZwt5Cm3kr5/s1600/SharePoint+2016+installation+-+marc+charmois+70+-+SharePoint+2016+installation+-+starting+sharepoint+2016+installation.png"></a><br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">5.2 - Running the SharePoint 2016 Products Preparation Tool (prerequisites installation)</div><br />
Before launching the SharePoint tools <span style="background-color:yellow">be sure that your virtual machine can access the Internet</span> because the tool will download a large amount of softwares. The SharePoint 2016 installation menu is opening... Click on install softwares prerequisites<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitt7jeJLpaJDDYtUXwUSrzyaBPDqjRKdJ74NjQJPmmlBAn14D7nmIxl_0ipwoyHWdHOy1s_oJxGROgXrEiq0jhvZGP30j6o2ClZnyYhrBSieh5iDwgMcbcs7lxCUMZW8qDEO5ULUpPDjhK/s1600/SharePoint+2016+installation+-+marc+charmois+71+-+SharePoint+2016+installation+-++sharepoint+2016+installation+menu.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitt7jeJLpaJDDYtUXwUSrzyaBPDqjRKdJ74NjQJPmmlBAn14D7nmIxl_0ipwoyHWdHOy1s_oJxGROgXrEiq0jhvZGP30j6o2ClZnyYhrBSieh5iDwgMcbcs7lxCUMZW8qDEO5ULUpPDjhK/s1600/SharePoint+2016+installation+-+marc+charmois+71+-+SharePoint+2016+installation+-++sharepoint+2016+installation+menu.png"></a><br />
<br />
First the SharePoint 2016 product preparation tool is summarizing the actions to be done...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0BzQkVUgZX1sHs0gpvHz3gejDPNW89TWyd3QDblv8YfcL6Rxll4pacgvD9waM6fmfWqb91-ieg0wpmKi1AbahDchiWG2-2dKSGdpCpnHxYdpWN3JySW567fJijuldqsB__TTq7bgV41_X/s1600/SharePoint+2016+installation+-+marc+charmois+72+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0BzQkVUgZX1sHs0gpvHz3gejDPNW89TWyd3QDblv8YfcL6Rxll4pacgvD9waM6fmfWqb91-ieg0wpmKi1AbahDchiWG2-2dKSGdpCpnHxYdpWN3JySW567fJijuldqsB__TTq7bgV41_X/s1600/SharePoint+2016+installation+-+marc+charmois+72+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png"></a><br />
<br />
Accept the licence terms...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnBW-c0jLxByzVGmQM5rYz8KNXzAA4poEdlzzdn3WYvZk8MgDdeDjIyQojkmsVfhbWbLEgzlN97zhr5nbHk7n7VWzP_HRm1Xeh3BI5LNw5P8RBJVF91FbcHRkl83bZYDZNLUkwaxKwcBb/s1600/SharePoint+2016+installation+-+marc+charmois+73+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnBW-c0jLxByzVGmQM5rYz8KNXzAA4poEdlzzdn3WYvZk8MgDdeDjIyQojkmsVfhbWbLEgzlN97zhr5nbHk7n7VWzP_HRm1Xeh3BI5LNw5P8RBJVF91FbcHRkl83bZYDZNLUkwaxKwcBb/s1600/SharePoint+2016+installation+-+marc+charmois+73+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png"></a><br />
<br />
The prerequisites are downloaded and installed by the SharePoint 2016 product preparation tool...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQLiOqKV_Zw2AoUG8KXzAvR_Mc2_MRPmxZ6j2WwK8ZRgH5Y7B-ENi5OWxdJuBMw1zhtvpy3nUnCeWCSls1KlIlvHPTk76yXVJPNXaxKbowTA9cAFjjZAfk4pxxu5EvxGiRwvsDjVl7SpJ/s1600/SharePoint+2016+installation+-+marc+charmois+74+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQLiOqKV_Zw2AoUG8KXzAvR_Mc2_MRPmxZ6j2WwK8ZRgH5Y7B-ENi5OWxdJuBMw1zhtvpy3nUnCeWCSls1KlIlvHPTk76yXVJPNXaxKbowTA9cAFjjZAfk4pxxu5EvxGiRwvsDjVl7SpJ/s1600/SharePoint+2016+installation+-+marc+charmois+74+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool.png"></a><br />
<br />
Finally, as we had properly configured the server, the prerequisites installation is successful. But you have to restart the server.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWo9oW1g8lAuZTnNeLCZTVAFXZZDxleE7qmj5Puf9kpnCtPiAAifC0sn3c2zwqujhZFYbJ9YizAMplCkLgKzC1Nfk17sky4qTq9EBM5IDrscGqIWmF6y98eVKA2oUTkGEGZOojcuD2IDx/s1600/SharePoint+2016+installation+-+marc+charmois+81+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool+successful.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWo9oW1g8lAuZTnNeLCZTVAFXZZDxleE7qmj5Puf9kpnCtPiAAifC0sn3c2zwqujhZFYbJ9YizAMplCkLgKzC1Nfk17sky4qTq9EBM5IDrscGqIWmF6y98eVKA2oUTkGEGZOojcuD2IDx/s1600/SharePoint+2016+installation+-+marc+charmois+81+-+SharePoint+2016+installation+-++sharepoint+2016+installation+products+preparation+tool+successful.png"></a><br />
<br />
After restarting the server, configuration is definitively successfull. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigwZstMYima6jdymQKMrAxJ4Z1XM_TFiCet6gnYfs9OUhvXZfn1WnKd9vjR-Amfr5kgVVXRMCf_w5QZExqEbBlFnAzdZGr2Kh9_1pY9R96R-w4wsAKyi6yclnCNigOnngfSiw-cJI4UTny/s1600/SharePoint+2016+installation+-+marc+charmois+84+-+SharePoint+2016+installation+-+prerequisites+successfully+installed.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigwZstMYima6jdymQKMrAxJ4Z1XM_TFiCet6gnYfs9OUhvXZfn1WnKd9vjR-Amfr5kgVVXRMCf_w5QZExqEbBlFnAzdZGr2Kh9_1pY9R96R-w4wsAKyi6yclnCNigOnngfSiw-cJI4UTny/s1600/SharePoint+2016+installation+-+marc+charmois+84+-+SharePoint+2016+installation+-+prerequisites+successfully+installed.png"></a><br />
<br />
Click on finish to close the SharePoint 2016 Products Preparation Tool. We are now really going to install SharePoint 2016. <br />
<br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">5.3 - Installing the SharePoint 2016 binaries</div><br />
Go back to the main SharePoint 2016 installation menu. This time click on "Install SharePoint Server". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1RKZv9kD0vdDs4UO0j-dU8Wwn-ENnKQlsgsoYBNV67zGN6n7X9XUW2bwD8uDWdoYc0OyxU9jwBSKD_UVd3XlIwhePT2fdi5NOuI6gtbsrRE2q-X3XavvUotFpQTxnKfZClVHHrVLuv6so/s1600/SharePoint+2016+installation+-+marc+charmois+85+-+SharePoint+2016+installation+-+install+SharePoint+server+2016.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1RKZv9kD0vdDs4UO0j-dU8Wwn-ENnKQlsgsoYBNV67zGN6n7X9XUW2bwD8uDWdoYc0OyxU9jwBSKD_UVd3XlIwhePT2fdi5NOuI6gtbsrRE2q-X3XavvUotFpQTxnKfZClVHHrVLuv6so/s1600/SharePoint+2016+installation+-+marc+charmois+85+-+SharePoint+2016+installation+-+install+SharePoint+server+2016.png"></a><br />
<br />
Accept the license terms<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSLZsUdswxGFv4DF2-pzc-kttjPU2nTViZoftCBX_tqnYLRjVt2Q7O_LaoZ724TM3VI_sa9Lb5COqV6eYVdHhs0CwE-si8VZ93cCgzMS0Jvz5-3sgxi1O4AILcGVH9zGuvH_uUr4JlghuN/s1600/SharePoint+2016+installation+-+marc+charmois+86+-+SharePoint+2016+installation+-+license+terms.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSLZsUdswxGFv4DF2-pzc-kttjPU2nTViZoftCBX_tqnYLRjVt2Q7O_LaoZ724TM3VI_sa9Lb5COqV6eYVdHhs0CwE-si8VZ93cCgzMS0Jvz5-3sgxi1O4AILcGVH9zGuvH_uUr4JlghuN/s1600/SharePoint+2016+installation+-+marc+charmois+86+-+SharePoint+2016+installation+-+license+terms.png"></a><br />
<br />
Copy and paste the product key that was in the SharePoint 2016 preview download page. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZUroCIYqY7ycyQL0LfrCszgVCcjySKsz5EauTH8fb8VBZVG4d4oAiiWPNrms3pjkGEs3yKOgCor1Wf6fAy-ZY2QX_KCMTn1eDAIN5sWVwSNMar4dqiHCikwmqyTIMx5O9TgOu13PwIewu/s1600/SharePoint+2016+installation+-+marc+charmois+86+-+SharePoint+2016+installation+-+product+key.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZUroCIYqY7ycyQL0LfrCszgVCcjySKsz5EauTH8fb8VBZVG4d4oAiiWPNrms3pjkGEs3yKOgCor1Wf6fAy-ZY2QX_KCMTn1eDAIN5sWVwSNMar4dqiHCikwmqyTIMx5O9TgOu13PwIewu/s1600/SharePoint+2016+installation+-+marc+charmois+86+-+SharePoint+2016+installation+-+product+key.png"></a><br />
<br />
Then, let the next config as it is since we have only one drive within our server...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWMW13Dd9GVbzUsQDhf-7J7YT1qFRGaSb4PF8kOWqp4kXufXr9U2VMRmR97N5XaeGUuozeKuUwlF6f5RnXgkJ1ks33d4oAbCuTrscd3atYWmu9YoeWTbAMPw7A-4YrK9H8KtqXY5qa3fKE/s1600/SharePoint+2016+installation+-+marc+charmois+87+-+SharePoint+2016+installation+-+files+locations.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWMW13Dd9GVbzUsQDhf-7J7YT1qFRGaSb4PF8kOWqp4kXufXr9U2VMRmR97N5XaeGUuozeKuUwlF6f5RnXgkJ1ks33d4oAbCuTrscd3atYWmu9YoeWTbAMPw7A-4YrK9H8KtqXY5qa3fKE/s1600/SharePoint+2016+installation+-+marc+charmois+87+-+SharePoint+2016+installation+-+files+locations.png"></a><br />
<br />
The SharePoint 2016 binaries are the installed on the server...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJIxwCmmNYNjv4q4Y7slPeO6BtPKkaLsHj56u-rz025YaJ87P4U8zJ-HDQ3TulNRwWD0ImydLhyB63D0Ga0BV8MrtI-4ISda4WC_hA4umKla5RI8HYtt5Dm-gcd2GqhC1ynymZf03xmq_/s1600/SharePoint+2016+installation+-+marc+charmois+88+-+SharePoint+2016+installation+-+finalizing+installation.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJIxwCmmNYNjv4q4Y7slPeO6BtPKkaLsHj56u-rz025YaJ87P4U8zJ-HDQ3TulNRwWD0ImydLhyB63D0Ga0BV8MrtI-4ISda4WC_hA4umKla5RI8HYtt5Dm-gcd2GqhC1ynymZf03xmq_/s1600/SharePoint+2016+installation+-+marc+charmois+88+-+SharePoint+2016+installation+-+finalizing+installation.png"></a><br />
<br />
At this point you can notice, that, on the server, the 14 and the 16 hive has been created. The 16 is for SharePoint 2016. The 14 seems to allow SharePoint 2010 to run on a SharePoint 2016 Farm. I will check this point. <br />
As I don't see 15 folder, I imagine that you can completely run SharePoint 2013 within the SharePoint 2016 "16" folder... to be verified also...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4oDDi8-AY61xft-00D3CU39n5jRmcjAdNBVgczgSr1JeV_X_SDR3dWXARKpWGKmMfjC17LpMO_zbFS0QXKGyNy8cYcmW5FM9BVndvnsFEtfnS28T3tRU6pBmRYp_FlwB7873hF9QCpzt_/s1600/SharePoint+2016+installation+-+marc+charmois+89+-+SharePoint+2016+installation+-+binaries+installed.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4oDDi8-AY61xft-00D3CU39n5jRmcjAdNBVgczgSr1JeV_X_SDR3dWXARKpWGKmMfjC17LpMO_zbFS0QXKGyNy8cYcmW5FM9BVndvnsFEtfnS28T3tRU6pBmRYp_FlwB7873hF9QCpzt_/s1600/SharePoint+2016+installation+-+marc+charmois+89+-+SharePoint+2016+installation+-+binaries+installed.png"></a><br />
<br />
And the SharePoint dll are in the new GAC (c:\windows\microsoft.net\assembly<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeiSwWNwnGnTZq_StUCxIeNACQoQQgplgFq_A9N8tCN1TA7ghmh7Ht0Kt9wWkpeacR5gQXYE30Cu2M9FCo62LU-AGo8_yGViXz4K8kF__Ui7-XfVPGbWZtj_31lq8IODI8moL5xdTrP1Bg/s1600/SharePoint+2016+installation+-+marc+charmois+88+-+SharePoint+2016+installation+-+sharepoint+dll.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeiSwWNwnGnTZq_StUCxIeNACQoQQgplgFq_A9N8tCN1TA7ghmh7Ht0Kt9wWkpeacR5gQXYE30Cu2M9FCo62LU-AGo8_yGViXz4K8kF__Ui7-XfVPGbWZtj_31lq8IODI8moL5xdTrP1Bg/s1600/SharePoint+2016+installation+-+marc+charmois+88+-+SharePoint+2016+installation+-+sharepoint+dll.png"></a><br />
<br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">5.4 - Creating the SharePoint 2016 Farm</div><br />
If we had activated the Domain Controler Role within our server we could have an Active Directory and could follow the installation with the SharePoint wizard. But as we are using only one account (Administrator) that is a local account, if we try to create a SharePoint Farm referencing this account, we will have the following exception: <br />
<br />
Local account should only be used in stand alone mode<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1X3-EgFzjsj1diGAxIDYJOVcDjdXGLCWwQXECnO0H16zh0OAXNO8Kxb9Jvcf96vpFOMjTOVvofmZO6kYgnVzLrzwXuZ44S85VJ-DWt_F741VR2BWsB8U1rFgPmpYjXUmlNfHz3dbd_LNn/s1600/SharePoint+2016+installation+-+marc+charmois+96+-+SharePoint+2016+installation+-+sharepoint+2016+configuration+wizard+05+cannot+use+local+acount.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1X3-EgFzjsj1diGAxIDYJOVcDjdXGLCWwQXECnO0H16zh0OAXNO8Kxb9Jvcf96vpFOMjTOVvofmZO6kYgnVzLrzwXuZ44S85VJ-DWt_F741VR2BWsB8U1rFgPmpYjXUmlNfHz3dbd_LNn/s1600/SharePoint+2016+installation+-+marc+charmois+96+-+SharePoint+2016+installation+-+sharepoint+2016+configuration+wizard+05+cannot+use+local+acount.png"></a><br />
<br />
The workaround is to use a shell instruction. so use the start menu and when arriving on the start screen type "SharePoint", in order to display all the SharePoint programs, and locate the SharePoint 2016 Management Shell. Click on it to open a command prompt... <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhnZ9u0NK8qfXyEuJFbhgg7Hgetbz_vbHf6B9QVIZkvqatI6q8RnGxGhqNoFy8EvrluuaQVh380Q-9iiE1w4sV5L6kms0Em7NXSwN2WFP3QhFMp4h06FQRxZ40QLBfOh_Xgn-3A1aAEsO/s1600/SharePoint+2016+installation+-+marc+charmois+97+-+SharePoint+2016+installation+-+locating+sharepoint+powershell.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhnZ9u0NK8qfXyEuJFbhgg7Hgetbz_vbHf6B9QVIZkvqatI6q8RnGxGhqNoFy8EvrluuaQVh380Q-9iiE1w4sV5L6kms0Em7NXSwN2WFP3QhFMp4h06FQRxZ40QLBfOh_Xgn-3A1aAEsO/s1600/SharePoint+2016+installation+-+marc+charmois+97+-+SharePoint+2016+installation+-+locating+sharepoint+powershell.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mkH-d99aLVHqn4v2GweTQPGHe7Z9Ion6PvmZGsoDWvHgvqek7PctuYo-xKUZCu_PzUdm6rUQozOZB05jTvYId-qX6Rr2RFGzbm-ft7u8C9-AaxHXSSYytbuj4fGlKjptQXJ7XXzXLDlJ/s1600/SharePoint+2016+installation+-+marc+charmois+98+-+SharePoint+2016+installation+-+sharepoint+powershell+open.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mkH-d99aLVHqn4v2GweTQPGHe7Z9Ion6PvmZGsoDWvHgvqek7PctuYo-xKUZCu_PzUdm6rUQozOZB05jTvYId-qX6Rr2RFGzbm-ft7u8C9-AaxHXSSYytbuj4fGlKjptQXJ7XXzXLDlJ/s1600/SharePoint+2016+installation+-+marc+charmois+98+-+SharePoint+2016+installation+-+sharepoint+powershell+open.png"></a><br />
<br />
Now it is the little touchy part for non technical people you have to type a command to create your SharePoint Farm : <br />
<br />
psconfig.exe -cmd configdb -create -server sp2016-local -database SharePoint_Config -user Administrator -password <span style="background-color:yellow">YOUR password</span> -passphrase P@ssw0rd -admincontentdatabase SharePoint_AdminContent -localserverrole SingleServerFarm<br />
<br />
If you have followed this tutorial carefully and named the computer as I did, the only diference between your command line and mine is the Administrator account pasword. If your server name is different you will have also to update the server name. <br />
<br />
Here are the screens you should obtain after executing the command : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn1MQLr5NBQrqsuf4iK0FPcmIEZhzDsDojegOqI75emZy8x5OWG5g8a67oGeszs-xYSBJVhEdD3rFJ-N3vO9r0W3Tpgux33lpl6I3wktWrw-uY7UOJH4_K4lcNxVITtgWiyE_5z45Rgavr/s1600/SharePoint+2016+installation+-+marc+charmois+99+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn1MQLr5NBQrqsuf4iK0FPcmIEZhzDsDojegOqI75emZy8x5OWG5g8a67oGeszs-xYSBJVhEdD3rFJ-N3vO9r0W3Tpgux33lpl6I3wktWrw-uY7UOJH4_K4lcNxVITtgWiyE_5z45Rgavr/s1600/SharePoint+2016+installation+-+marc+charmois+99+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieW0bsYSl1P1-txYQYc6ArbA-U6W18Git-7TFS1RqoQsVsPHa1CvVFy1IkWxzW0xJBgrrEsCkZT1B39H7Nwzip86_VzN8OIDzHWlOE6h95sGovucjKYxYzNj9qrEgdlBNqqlXC-GJcU961/s1600/SharePoint+2016+installation+-+marc+charmois+100+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe+executing.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieW0bsYSl1P1-txYQYc6ArbA-U6W18Git-7TFS1RqoQsVsPHa1CvVFy1IkWxzW0xJBgrrEsCkZT1B39H7Nwzip86_VzN8OIDzHWlOE6h95sGovucjKYxYzNj9qrEgdlBNqqlXC-GJcU961/s1600/SharePoint+2016+installation+-+marc+charmois+100+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe+executing.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ZsBE4n8-Nbi93Fa7UzBHqEeDFlGhYZohWtPzWpvzgNSehCJurl13HtcTxyciwcJ5tyWatuu-6KZEBmXFq5cRYYqY2mS56SoQxuE2OkTFwDTb6QE1XbrEzSVuRuFKlb3yuHAkM-wTI4Cv/s1600/SharePoint+2016+installation+-+marc+charmois+101+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe+configuration+successful.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ZsBE4n8-Nbi93Fa7UzBHqEeDFlGhYZohWtPzWpvzgNSehCJurl13HtcTxyciwcJ5tyWatuu-6KZEBmXFq5cRYYqY2mS56SoQxuE2OkTFwDTb6QE1XbrEzSVuRuFKlb3yuHAkM-wTI4Cv/s1600/SharePoint+2016+installation+-+marc+charmois+101+-+SharePoint+2016+installation+-+sharepoint+powershell+psconfig.exe+configuration+successful.png"></a><br />
<br />
After that, you will notice that the databases have been created: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9TdWvrOrUQTZv_AKmyBmMU-t9hvVvHUGVANeBB6Tliowb1cmMTO42MUfMvMy7wk24jaalD76Lp9qBRP46iJf1B3TuEAd7LrvLsY60gZbIsu8eEWDEHq87iYOzz7bJ4ojFtKcIx9_Ua74F/s1600/SharePoint+2016+installation+-+marc+charmois+102+-+SharePoint+2016+installation+-+sharepoint+database+successfully+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9TdWvrOrUQTZv_AKmyBmMU-t9hvVvHUGVANeBB6Tliowb1cmMTO42MUfMvMy7wk24jaalD76Lp9qBRP46iJf1B3TuEAd7LrvLsY60gZbIsu8eEWDEHq87iYOzz7bJ4ojFtKcIx9_Ua74F/s1600/SharePoint+2016+installation+-+marc+charmois+102+-+SharePoint+2016+installation+-+sharepoint+database+successfully+created.png"></a><br />
<br />
Internet Information Services has been configured successfully also: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLRmUHpS0TMjw7FNJAyS2LptLo8NTw2eOvUFAUdAOZZJDy7CO1zPNRp7sTAN7NUC5deQj6nbWNAg0-wjgY8IkabYtXUvl9ppNOotmqipsPrKafXv9Y0L6xCTAar_NO3_OJgsk3EmWGjD_9/s1600/SharePoint+2016+installation+-+marc+charmois+103+-+SharePoint+2016+installation+-+sharepoint+ISS+configuration+successfully+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLRmUHpS0TMjw7FNJAyS2LptLo8NTw2eOvUFAUdAOZZJDy7CO1zPNRp7sTAN7NUC5deQj6nbWNAg0-wjgY8IkabYtXUvl9ppNOotmqipsPrKafXv9Y0L6xCTAar_NO3_OJgsk3EmWGjD_9/s1600/SharePoint+2016+installation+-+marc+charmois+103+-+SharePoint+2016+installation+-+sharepoint+ISS+configuration+successfully+created.png"></a><br />
<br />
and same thing for the server services dedicated to SharePoint : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZKRYq2AfTQx38kk0ojP4dUefIA__MID5zZsH1AsSDoeSmX7hxBMY0fY-H82s-2RJNR0M1Il5DHcQeOpKpMZQggG1eMrSOX6lxHJUheVgf4CaKj8jM3JnEshBitRybitWMV8DbZH3t-_j3/s1600/SharePoint+2016+installation+-+marc+charmois+104+-+SharePoint+2016+installation+-+sharepoint+services+configuration+successfully+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZKRYq2AfTQx38kk0ojP4dUefIA__MID5zZsH1AsSDoeSmX7hxBMY0fY-H82s-2RJNR0M1Il5DHcQeOpKpMZQggG1eMrSOX6lxHJUheVgf4CaKj8jM3JnEshBitRybitWMV8DbZH3t-_j3/s1600/SharePoint+2016+installation+-+marc+charmois+104+-+SharePoint+2016+installation+-+sharepoint+services+configuration+successfully+created.png"></a><br />
<br />
That is to mean: you have a SharePoint Farm running on your Server. Last thing to do: enable the SharePoint Central Administration to administrate the Farm and create new sites, new content, etc...<br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">5.5 - Provisioning the Central Administration Site for the SharePoint 2016 Farm</div><br />
Using the Start Screen of the server, type "SharePoint" to locate the SharePoint Products Wizard and launch it. The wizard detects the Farm we have just created. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXXG0wG-13xiP8G9DK0Tvm55aX0BJRCy218MhjRFuzTp_vVxdEdNs-G545y6Mqm94eNWi7Xw26fqE9Ex-XRybovQBS1LYgZNlYm0EdK0PbYL2RI1p-6xXd-ImcfLPQnOdX5fLNrlhA1asf/s1600/SharePoint+2016+installation+-+marc+charmois+105+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+01.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXXG0wG-13xiP8G9DK0Tvm55aX0BJRCy218MhjRFuzTp_vVxdEdNs-G545y6Mqm94eNWi7Xw26fqE9Ex-XRybovQBS1LYgZNlYm0EdK0PbYL2RI1p-6xXd-ImcfLPQnOdX5fLNrlhA1asf/s1600/SharePoint+2016+installation+-+marc+charmois+105+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+01.png"></a><br />
<br />
Click next, and provide a number easy to remember for the port of the Central Admin Site (I always use 55555). Let the NTLM option checked. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW4vu3tkn7X3JEpunwYGx68VkUqZrlOyfkzzv8X0lXyMCswUjoAHyIZjbPololxhCMFs8hzzmWXh_Q_rNJVFRu0yiF1i9Hq6qtwOSTYI0aSy2hZjCNiyrfNcsWf2tmAaE-veDUHD9d32nG/s1600/SharePoint+2016+installation+-+marc+charmois+106+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+02.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW4vu3tkn7X3JEpunwYGx68VkUqZrlOyfkzzv8X0lXyMCswUjoAHyIZjbPololxhCMFs8hzzmWXh_Q_rNJVFRu0yiF1i9Hq6qtwOSTYI0aSy2hZjCNiyrfNcsWf2tmAaE-veDUHD9d32nG/s1600/SharePoint+2016+installation+-+marc+charmois+106+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+02.png"></a><br />
<br />
Then, the wizard summarizes your choices...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK94zJAkffJvNOfPGrakaEZ4Ub4rh-rvgNkuCJ0smIY-E0Bxo3dug3B9fOX7I7YTjAh_PNZ7ROFOv_UmRgx5oFVUXTFRQ1Gjtj1XMnm3B4rpv7571oP5TLFdQOQLb6oVtBYOvmy2_WB-2M/s1600/SharePoint+2016+installation+-+marc+charmois+107+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+03.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK94zJAkffJvNOfPGrakaEZ4Ub4rh-rvgNkuCJ0smIY-E0Bxo3dug3B9fOX7I7YTjAh_PNZ7ROFOv_UmRgx5oFVUXTFRQ1Gjtj1XMnm3B4rpv7571oP5TLFdQOQLb6oVtBYOvmy2_WB-2M/s1600/SharePoint+2016+installation+-+marc+charmois+107+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+03.png"></a><br />
<br />
Launch the wizard to provision the SharePoint Farm Central Administration Site... <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihjjDXHC3i22INR1t9Pl-nJjoawbMxS0n3ru43_Vdr-ya5CS9vqaf0CoWaAj-PxjLA3Q-93jA2TaYSSCktX9sxDHAzol6BFNmGftQsxzoYubdOO62AH_OIud9VHy5Rst1_-vXedSOppUcU/s1600/SharePoint+2016+installation+-+marc+charmois+108+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+04.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihjjDXHC3i22INR1t9Pl-nJjoawbMxS0n3ru43_Vdr-ya5CS9vqaf0CoWaAj-PxjLA3Q-93jA2TaYSSCktX9sxDHAzol6BFNmGftQsxzoYubdOO62AH_OIud9VHy5Rst1_-vXedSOppUcU/s1600/SharePoint+2016+installation+-+marc+charmois+108+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+04.png"></a><br />
<br />
You are warned that the configuration was successful<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLTZIsmxxB-ngVAc4Nsdts5NzL1AQHbWxirYkyElIksgnOGAvmmFfaGwxgW01iCOQV_VUjEaq2hovnxSGB_eJKbQ1hF7c1IlTqMf8jOGQ5HwxaQxpKjFkrUZZL181DDeWq7eEtIrwGG3kx/s1600/SharePoint+2016+installation+-+marc+charmois+109+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+05+configuration+successful.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLTZIsmxxB-ngVAc4Nsdts5NzL1AQHbWxirYkyElIksgnOGAvmmFfaGwxgW01iCOQV_VUjEaq2hovnxSGB_eJKbQ1hF7c1IlTqMf8jOGQ5HwxaQxpKjFkrUZZL181DDeWq7eEtIrwGG3kx/s1600/SharePoint+2016+installation+-+marc+charmois+109+-+SharePoint+2016+installation+-+sharepoint+2016+product+wizard+05+configuration+successful.png"></a> <br />
<br />
And when you close the window, the Central Administration Site is called... and you have first to answer to the participation at the Improvement Program<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsA7yMjpO6-ZvdxJ9HUNJAcGJpHYyT2kvRIzvYLxGVHFHcT6tfpw2iLpWypGHhRb7-jmCn2Uy5G8YvGAbVqdIBf7H9wG8HT5aSaWD6X8sS1s_FOKIweimw07-gOXue2L-1vi8pIIiG1UMI/s1600/SharePoint+2016+installation+-+marc+charmois+110+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+displaying+pop_up+for+participation+to+improvment+program.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsA7yMjpO6-ZvdxJ9HUNJAcGJpHYyT2kvRIzvYLxGVHFHcT6tfpw2iLpWypGHhRb7-jmCn2Uy5G8YvGAbVqdIBf7H9wG8HT5aSaWD6X8sS1s_FOKIweimw07-gOXue2L-1vi8pIIiG1UMI/s1600/SharePoint+2016+installation+-+marc+charmois+110+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+displaying+pop_up+for+participation+to+improvment+program.png"></a><br />
<br />
Then, you are asked for using a wizard to configure the services. Don't use it and cancel the wizard. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcvQjBzD5iD9xoMKiTdF1bZmi0rc4TJGDzBhIKr8QA-3R1pW4ecz3mQWuCmv31SfM6-MS4yhRKntXAQ3C9JBEqCyp-ZdkKafdFAIQOTu3CXbK7YQlXT6l7mtD9JgjXzt49PngiKDV5j1ex/s1600/SharePoint+2016+installation+-+marc+charmois+111+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+configuration+wizard.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcvQjBzD5iD9xoMKiTdF1bZmi0rc4TJGDzBhIKr8QA-3R1pW4ecz3mQWuCmv31SfM6-MS4yhRKntXAQ3C9JBEqCyp-ZdkKafdFAIQOTu3CXbK7YQlXT6l7mtD9JgjXzt49PngiKDV5j1ex/s1600/SharePoint+2016+installation+-+marc+charmois+111+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+configuration+wizard.png"></a><br />
<br />
When closing the wizard the SharePoint 2016 Central Administration Site is finally displaying...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj46IlZhXgT-2MS0Gb3iUWIbTs4e9U_L49q9E6QHOuLc3miSaBPyJWcR6XLAYclhFMQ2ILmfCguWqGbS8QCwp6KHaz8GhY8CxtzYSjY4-MhqCr6ALEnga0ahm3RMZ23ntKzOU2iN19wLgBG/s1600/SharePoint+2016+installation+-+marc+charmois+112+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+installation+succesfull.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj46IlZhXgT-2MS0Gb3iUWIbTs4e9U_L49q9E6QHOuLc3miSaBPyJWcR6XLAYclhFMQ2ILmfCguWqGbS8QCwp6KHaz8GhY8CxtzYSjY4-MhqCr6ALEnga0ahm3RMZ23ntKzOU2iN19wLgBG/s1600/SharePoint+2016+installation+-+marc+charmois+112+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+installation+succesfull.png"></a><br />
<br />
Don't mind for the health analyzer issues. It is normal because we didn't follow the best practices since we wanted to quickly mount a trial SharePoint environment. <br />
You have anyway installed SharePoint 2016 on premises successfully. <b>Well done!</b><br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">6 - Testing the SharePoint 2016 installation on Windows Server 2012 R2</div><div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">6.1 - Creating a new Web Application</div>On the SharePoint 2016 Central Administration locate the "Manage Web Applications" link button and click on it.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-8ZqPIJX1iHD8pkdhVyebE9YwXHd6YpZlcnepBUdgFJw34ym5bWMJCRkzwvnRrt7qFxfsqs_idrFRVXBM9dhE08dBd-KkaaJxcJRXd1bTj9ILtpm_P06DPMUub2JbmIGQdPZFNn-xXOs-/s1600/SharePoint+2016+installation+-+marc+charmois+113+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+manage+web+applications.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-8ZqPIJX1iHD8pkdhVyebE9YwXHd6YpZlcnepBUdgFJw34ym5bWMJCRkzwvnRrt7qFxfsqs_idrFRVXBM9dhE08dBd-KkaaJxcJRXd1bTj9ILtpm_P06DPMUub2JbmIGQdPZFNn-xXOs-/s1600/SharePoint+2016+installation+-+marc+charmois+113+-+SharePoint+2016+installation+-+sharepoint+2016+central+admin+-+manage+web+applications.png"></a><br />
<br />
Using the "New" button of the Ribbon diplay the pop-up for creating a new web application. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO4Q9i3KMohhfSn2greIYjQQbZYuMCFAYEXmT2PSZoV2Nk9Z6ZORQ6y_mULzAE1y4Y8NYRjkHn8AsCAGjcOdIvZsoe2wf1hwoMT9xo41Wz6bI_mQc-56vyZ05dEpweol4oyvUMoeiW2wkJ/s1600/SharePoint+2016+installation+-+marc+charmois+113+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+manage+web+applications.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO4Q9i3KMohhfSn2greIYjQQbZYuMCFAYEXmT2PSZoV2Nk9Z6ZORQ6y_mULzAE1y4Y8NYRjkHn8AsCAGjcOdIvZsoe2wf1hwoMT9xo41Wz6bI_mQc-56vyZ05dEpweol4oyvUMoeiW2wkJ/s1600/SharePoint+2016+installation+-+marc+charmois+113+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+manage+web+applications.png"></a><br />
<br />
On the pop-up, let all the automatic settings except the content database name<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWwiXCnuDUX_KeFTYSZGuPrFgFnnz6Ujp6oclLtFlRIqx5rOQVrCTjNn5cgvpi_P20iLjCt5lIB0SQeD5HGlTsxatsTUJbyedthNoV1qj2KdpLGbR07VUTUQqXYQ0AxSThriuXh17D53zl/s1600/SharePoint+2016+installation+-+marc+charmois+114+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWwiXCnuDUX_KeFTYSZGuPrFgFnnz6Ujp6oclLtFlRIqx5rOQVrCTjNn5cgvpi_P20iLjCt5lIB0SQeD5HGlTsxatsTUJbyedthNoV1qj2KdpLGbR07VUTUQqXYQ0AxSThriuXh17D53zl/s1600/SharePoint+2016+installation+-+marc+charmois+114+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application.png"></a><br />
<br />
When the Web Application is created this pop-up is displaying: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsu8C8bs5MebBHMddusj2Oq97nzAtwcNSNi-edt7hwEcMMvrsytKoTfBvnjAvFx1l3bVNmfWFvz8SQQFprqpIWpa1qhKIAuLraXz0kf_-TwHV-FpH4PMQJWDG5klzEGtl-zEg-ZPgBHSnA/s1600/SharePoint+2016+installation+-+marc+charmois+115+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsu8C8bs5MebBHMddusj2Oq97nzAtwcNSNi-edt7hwEcMMvrsytKoTfBvnjAvFx1l3bVNmfWFvz8SQQFprqpIWpa1qhKIAuLraXz0kf_-TwHV-FpH4PMQJWDG5klzEGtl-zEg-ZPgBHSnA/s1600/SharePoint+2016+installation+-+marc+charmois+115+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application+created.png"></a> <br />
<br />
When you close it you can notice that the Web Application has been created succesfully. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ6sgmx17sSZHTPvEA3qlIT9Tq5FZp0XoH7shuTH9fLh-5fywYOMesoQWz1K3z6BdS4YOZz1yU0HodqRL9XmN_FxzhmVQuwfujV4dwERlCwlC1FfFTSgCQ7PBl2nCycObxonPZCesp2I9t/s1600/SharePoint+2016+installation+-+marc+charmois+116+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ6sgmx17sSZHTPvEA3qlIT9Tq5FZp0XoH7shuTH9fLh-5fywYOMesoQWz1K3z6BdS4YOZz1yU0HodqRL9XmN_FxzhmVQuwfujV4dwERlCwlC1FfFTSgCQ7PBl2nCycObxonPZCesp2I9t/s1600/SharePoint+2016+installation+-+marc+charmois+116+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+new+web+application+created.png"></a><br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">6.2 - Creating a new Site Collection</div>Close the Pop-Up, go back to the Central Administration Home page and this time click on the "create site collections" link. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Mq-Mb5IeI5omSVtgdRUVJpBxUKxQ3kUk2CE1h1-LzPzlfREhq3EbZgzB6IQj7BH445l4WGdQz666hpkmmx-9IkfP7z4WZyZ_Q8bXJCX6cBmQ1mFK14ZNcwvEpNbPUzLUpLNntiFAr0_0/s1600/SharePoint+2016+installation+-+marc+charmois+117+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+00.png" imageanchor="1" ><img border="0" class="screenshot-standard" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Mq-Mb5IeI5omSVtgdRUVJpBxUKxQ3kUk2CE1h1-LzPzlfREhq3EbZgzB6IQj7BH445l4WGdQz666hpkmmx-9IkfP7z4WZyZ_Q8bXJCX6cBmQ1mFK14ZNcwvEpNbPUzLUpLNntiFAr0_0/s1600/SharePoint+2016+installation+-+marc+charmois+117+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+00.png"></a><br />
<br />
Just populate the site name and choose your Admin account as the Site Collection primary administrator. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNR1gwtYiuIPDl6dZ-6VXL6aX11X3ZRFZV7fu4Eq77qR248SyUq4UgTddWla3dJB6oXuY9JA9NnQpfjNP-HCHJxyiaG-ArrsSNkJeUudzvOYfydVp8Xq48Cr_8UmU7DIha6tdToGTRsgLB/s1600/SharePoint+2016+installation+-+marc+charmois+117+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+01.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNR1gwtYiuIPDl6dZ-6VXL6aX11X3ZRFZV7fu4Eq77qR248SyUq4UgTddWla3dJB6oXuY9JA9NnQpfjNP-HCHJxyiaG-ArrsSNkJeUudzvOYfydVp8Xq48Cr_8UmU7DIha6tdToGTRsgLB/s1600/SharePoint+2016+installation+-+marc+charmois+117+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+01.png"></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrkUKKiNFoGY4vS-6Ma5gHXLj7e-Kq_v9d6W7gb3IkqxYoOZxNSfk-fbK_NtEnoL8OdZlkVfRYqJZN8LtLYfTtgDmZVnrtrOofp0ihZbovHZfq4X0XvI1ya2OKRkvBtdtf-bZamH5WOtw5/s1600/SharePoint+2016+installation+-+marc+charmois+118+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+02.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrkUKKiNFoGY4vS-6Ma5gHXLj7e-Kq_v9d6W7gb3IkqxYoOZxNSfk-fbK_NtEnoL8OdZlkVfRYqJZN8LtLYfTtgDmZVnrtrOofp0ihZbovHZfq4X0XvI1ya2OKRkvBtdtf-bZamH5WOtw5/s1600/SharePoint+2016+installation+-+marc+charmois+118+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+create+site+collection+02.png"></a><br />
<br />
You are then warned that the Site Collection has been successfully created...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAGpIZwGM9Zd877i7_IsioaPGTjHYzxnupC-Av1kULEldAaigNMNgg8U6o1g8c2dHX_YKwDxqZ62ouwuy2dtmggZbt8703mYbIHEHD30Yr9jwdffcZ0M91oMJ3_BJjZ5NLgI19s9nPm5nf/s1600/SharePoint+2016+installation+-+marc+charmois+119+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+site+collection+created.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAGpIZwGM9Zd877i7_IsioaPGTjHYzxnupC-Av1kULEldAaigNMNgg8U6o1g8c2dHX_YKwDxqZ62ouwuy2dtmggZbt8703mYbIHEHD30Yr9jwdffcZ0M91oMJ3_BJjZ5NLgI19s9nPm5nf/s1600/SharePoint+2016+installation+-+marc+charmois+119+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+site+collection+created.png"></a><br />
<br />
And when you click the new Site Collection link you are redirected to its landing page. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6DnxSMbhtD0gKlGnfpPF_V_ueS9CRZwVtDeRWxMQ2Vbk9CCQt7H0egJeZ-b3SjY8PhaJWMs5N1zY0QG2LG1jKsWh2QDCz6fXyxpf14XZ_gh5nadqX70ETT1yj9g6F3_V_GOHrs7eSmU37/s1600/SharePoint+2016+installation+-+marc+charmois+120+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+site+collection+root+web+displaying.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6DnxSMbhtD0gKlGnfpPF_V_ueS9CRZwVtDeRWxMQ2Vbk9CCQt7H0egJeZ-b3SjY8PhaJWMs5N1zY0QG2LG1jKsWh2QDCz6fXyxpf14XZ_gh5nadqX70ETT1yj9g6F3_V_GOHrs7eSmU37/s1600/SharePoint+2016+installation+-+marc+charmois+120+-+SharePoint+2016+installation+testing+-+sharepoint+2016+central+admin+-+site+collection+root+web+displaying.png"></a><br />
<br />
You can now be sure that your SharePoint 2016 installation is working properly. <br />
<br />
</div>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com7tag:blogger.com,1999:blog-4357140756496246910.post-61677147765316598952015-10-27T18:23:00.003+01:002019-09-05T20:51:00.908+02:00Programmatically post a message to Yammer from SharePoint Online
<div class="h2-paragraph">
In <a href="http://mosshowto.blogspot.fr/2015/10/programmatically-embed-yammer.html">my previous post</a>, I showed how to programmatically embed a Yammer feed into a SharePoint Online page, using the JavaScript SDK for Yammer and the Yammer REST API. In this post I will show how to post a message into a Yammer group from a SharePoint Online page, using again the JavaScript SDK for Yammer and the Yammer REST API. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihZsd2FWKFfWwTU9v7XDg5qYJVSYI8RC_C9Y2B0IsCS5-F7m62yYQ9W13bFWoSBlnIwsmcLgXUU0E4z-c0xnOiBPGpejCCm-G0-xgLgKwyznGFroIuRRL4aIUo7f9u-A1bX-E8oBmjl_k3/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+01+-+demo+01.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihZsd2FWKFfWwTU9v7XDg5qYJVSYI8RC_C9Y2B0IsCS5-F7m62yYQ9W13bFWoSBlnIwsmcLgXUU0E4z-c0xnOiBPGpejCCm-G0-xgLgKwyznGFroIuRRL4aIUo7f9u-A1bX-E8oBmjl_k3/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+01+-+demo+01.png"></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghlAfAewDGSLAR3RAGUmA-m6VJcnRhG25BlMRWe3xjmfBUTaE37lUOesDH6oNmUKAIspAKJs0UFyOSS3e9SGrLbAMtto4dJmS_HFM_c4006-Uqr4pt_SdOiBoBIJY_34NMN0t7jncs_l2I/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+02+-+demo+02.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghlAfAewDGSLAR3RAGUmA-m6VJcnRhG25BlMRWe3xjmfBUTaE37lUOesDH6oNmUKAIspAKJs0UFyOSS3e9SGrLbAMtto4dJmS_HFM_c4006-Uqr4pt_SdOiBoBIJY_34NMN0t7jncs_l2I/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+02+-+demo+02.png"></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinvCfhqhsySYL-M35kcvVXEMFJLBcgWWzE_7pYHs74kyIfsUcrVYhD5YT_lVzPThJsGT_EMleGsTW1zu6B8crgrBtd7i-mSsRhIyc-NiwdyrJar-CRVPTXeVk_vQb6uQ4vOS90Jmqj0NXx/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+03+-+demo+03.png" imageanchor="1" ><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinvCfhqhsySYL-M35kcvVXEMFJLBcgWWzE_7pYHs74kyIfsUcrVYhD5YT_lVzPThJsGT_EMleGsTW1zu6B8crgrBtd7i-mSsRhIyc-NiwdyrJar-CRVPTXeVk_vQb6uQ4vOS90Jmqj0NXx/s1600/Programmaticcally+post+a+message+to+Yammer+from+SharePoint+on+line+-+marc+charmois+03+-+demo+03.png"></a><br />
<br />
<h2>1 - Adding a new feature to post a message to a Yammer group, from SharePoint on line</h2><br />
In <a href="http://mosshowto.blogspot.fr/2015/10/programmatically-embed-yammer.html">my previous post (the one for displaying the Yammer feed into SharePoint Online)</a> I have explained why you have to create a Yammer App and how to do it. I also explained the basis of programming for Yammer with the Yammer Javascript SDK and the REST API. I advice you to do the previous tutorial. <br />
<br />
Here, I will just explain some pieces of the code. You will find the complete page on the dedicated <a href="https://github.com/MarcCharmois/Post-to-Yammer-from-SharePoint-Online">GitHub repositery</a>. <br />
<br />
The first function gets the Yammer topic value (selected by the user with the radio button). It is the place to manage authentication if needed. I have managed authentication for the getMyFeed function. It is explained also in the previous post. <br />
<br />
</div>
<pre class="code-standard">function postMessage() {
topicToPost=getTopicValue();
yamPostRequest(this);
/*If needed you have to manage authentication as in the script "authentication" I used for getting the feed (line 130)*/
}
</pre><br />
<div class="h2-paragraph">
then you send the post to Yammer after having checked that no elements are missing. Because you cannot send a topic with an empty value you have to check if there is a topic:<br />
</div>
<pre class="code-standard">if (topicToPost.length>0){
yam.platform.request(
{
url: "https://api.yammer.com/api/v1/messages.json"
, method: "POST"
, data: {
"body" : msg_value
,"group_id" : groupID
,topic1 : topicToPost
,"cc": "[[user:1557787745]],[[user:1557794361]]"//use your own user ID to notify them
//,direct_to_id : "1537569057" seems not to work
,"skip_body_notifications" : "true"
}
, success: function (msg) {
document.getElementById('msg_body').value="";
//alert("Post was Successful!");
}
, error: function (msg) { //alert("Your message cannot be published\nThe request to Yammer didn't work... ");
}
})
}else {
//if there is no topic you do the same request except you avoid the "topic1" parameter
}
</pre><br />Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com4tag:blogger.com,1999:blog-4357140756496246910.post-47491048767791164062015-10-26T00:47:00.002+01:002019-09-05T17:17:53.847+02:00Programmatically embed a Yammer feed into a SharePoint Online site<div class="h2-paragraph">
In this post I will show how to use JavaScript and the Yammer SDK for easily embedding a Yammer feed into a SharePoint Online team site. <br />
<br />
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqXlqqKT5zro_1vHykl0CygMJYt80aKMZ4avwbQqWajHZgdblq7xpLPRLIPrO6b6HmcgZ3wFWf0qGqUfsszZtv0K64flkVImvcEXOT2CmtS6Bsz8jtHZgz7X7LngwurgEFKFxqchiGN_A6/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+001+-+Yammer+Feed.png" imageanchor="1" ><img class="screenshot-standard" style="width:100%" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqXlqqKT5zro_1vHykl0CygMJYt80aKMZ4avwbQqWajHZgdblq7xpLPRLIPrO6b6HmcgZ3wFWf0qGqUfsszZtv0K64flkVImvcEXOT2CmtS6Bsz8jtHZgz7X7LngwurgEFKFxqchiGN_A6/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+001+-+Yammer+Feed.png" /></a>
<br />
<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsfvyEol6BK-vFmDmHQc341sUl8haNDInVDH3VrOH7dUnejTWxP0h8irBnyMtgjcTsOWWCWhpx5Vv-feluax65f5OLplGkpEdhLK5Ywx4-ckZoWisab2n1h61dj11PYVzk0SUOQcXZCCtg/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+002+-+Yammer+Feed+within+Intranet+Home+Page.png" imageanchor="1" >
<img class="screenshot-standard" style="width:100%" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsfvyEol6BK-vFmDmHQc341sUl8haNDInVDH3VrOH7dUnejTWxP0h8irBnyMtgjcTsOWWCWhpx5Vv-feluax65f5OLplGkpEdhLK5Ywx4-ckZoWisab2n1h61dj11PYVzk0SUOQcXZCCtg/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+002+-+Yammer+Feed+within+Intranet+Home+Page.png" /></a>
<br />
<br>
<div style="clear:both;"></div><br />
<br />
I will show 2 different approaches and will explain the pros and the cons of each : <br />
<br />
- the first approach is the Yammer Embed and is a good initiation to the topic<br />
- the second uses more advanced knowledge regarding the Yammer SDK<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">1 - Regarding environments</div>I have also to write something regarding the available environements for testing. Either you have a Yammer available at your company or at your client place, or you have to mount your own environmement (that I did). The important thing is to log to Yammer with an account that is not an external account. <a href="http://stackoverflow.com/questions/29276419/yammer-can-no-longer-access-messages-from-other-network-using-yammer-api">Programming with the SDK doesn't work for external accounts</a> any longer since 2015. <br />
Thus, don't think to make this tutorial work by using a trial version of SharePoint Online and a Yammer you can access with an external account. It won't work. (Except for Yammer embed). <br />
<br />
If you want to mount a trail environment as I did, you need to subscibe to <a href="https://products.office.com/en-us/business/office-365-enterprise-e3-business-software">the Office 365 Enterprise E3 trial offer</a> that is the only one which with you can get Yammer. But be careful. To make SharePoint Online and Yammer works properly with this Office 365 Enterprise E3 trial offer <span style="background-color:yellow"><a href="https://community.office365.com/en-us/f/148/t/403703?ss-src=related">you will have to buy a Domain.</a></span><br />
<br />
- Here is the part of the Yammer activation guide that explains <a href="https://support.office.com/en-us/article/Yammer-activation-guide-4f924c74-87d2-49d0-a4f6-cba3ce2b0e7c">how to add a company Domain for your Office 365 environment.</a> <br />
<br />
- And the <a href="https://support.office.com/en-us/article/Frequently-asked-questions-Yammer-activation-guide-4f6763f4-23e2-43b0-a554-08931295e863?ui=en-US&rs=en-US&ad=US">Yammer Activation Guide FAQ</a><br />
<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">2 - The Yammer Embed approach</div><br />
You will find a lot of post explaining how to add a Yammer Embed to a SharePoint Online page. Here is the <a href="https://support.office.com/en-my/article/Yammer-App-for-SharePoint-Add-a-Yammer-feed-to-a-SharePoint-page-8023e402-5ca3-4ef4-a2da-37215aa75f49?ui=en-US&rs=en-MY&ad=MY">official documentation of Microsoft</a> that is also announcing that the Yammer App for SharePoint 2013 will be discontinued and will stop working on September 15th, 2015. Yammer Embed will be our single solution to integrate Yammer feeds into SharePoint. <br />
<br />
Yammer Embed is limited. As it is displaying the feed within an Iframe, it is not so easy to customize the feed as you should want, for example change the styles, the fonts size, the font family, color, etc. <br />
However, there is some parameters you can add to the code to modify the way Yammer Embed is displaying. I will illustrate that with and example. Look at a page with the Yammer Embed on it: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGX7v-x3vKjDtouah5j9QP-iEJPwZDn8OrbT0JKr9vHtiEAfLiQ7vGdv9I0VygnOguaY2UhDaxsGha4-sTH50_-72WWa66GtL_ffrW3kSyHbc4VVz71_AdlHJNkTf8NmF6_UROmDnQ3zEN/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+002+-+Yammer+Feed+within+Intranet+Home+Page.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGX7v-x3vKjDtouah5j9QP-iEJPwZDn8OrbT0JKr9vHtiEAfLiQ7vGdv9I0VygnOguaY2UhDaxsGha4-sTH50_-72WWa66GtL_ffrW3kSyHbc4VVz71_AdlHJNkTf8NmF6_UROmDnQ3zEN/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+002+-+Yammer+Feed+within+Intranet+Home+Page.png"></a><br />
<br />
You will notice that the header is showing the Domain I had to buy to mount my Office 365 Enterprise E3 trial environment. Assume you want to hide this header. For doing that you have to add to the Yammer Embed code the following instruction: <br />
<br />
config :{<br />
header: false<br />
}<br />
<br />
Here is the Yammer embed code after having done that : <br />
<br />
<script type="text/javascript" src="https://assets.yammer.com/assets/platform_embed.js"></script><br />
<script type="text/javascript"> yam.connect.embedFeed({<br />
container: "#embedded-feed",<br />
network: "marccharmois.com",<br />
feedType: "group",<br />
feedId: "6574317",<br />
config :{<br />
header: false<br />
}<br />
});<br />
</script><br />
<br />
...and the result...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsOL4i-2moA9Dps3nkGYYm47HAYrpsbvUCOsJtDzNKNk7o7rxiVJXMuxAlmtpbelv01bput0lOirIFN6UykG7SrW82ley0zOld5qFssfgyAFqRAXFDmfDP7tGgUcDuU9Z0_HZbEQJ4gfPl/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+003+-+Yammer+Feed+within+Intranet+Home+Page+without+header.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsOL4i-2moA9Dps3nkGYYm47HAYrpsbvUCOsJtDzNKNk7o7rxiVJXMuxAlmtpbelv01bput0lOirIFN6UykG7SrW82ley0zOld5qFssfgyAFqRAXFDmfDP7tGgUcDuU9Z0_HZbEQJ4gfPl/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+003+-+Yammer+Feed+within+Intranet+Home+Page+without+header.png"></a><br />
<br />
That gives you already a good idea about the way you can give instructions to Yammer by using the JavaScript SDK. It is like working on fragments of JQuery Ajax request .<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">3 - The Yammer JavaScript SDK and REST API approcah</div><br />
Now is the time to examine a more powerful approach that allows you embed a Yammer feed into a SharePoint page while being able to customize things the way you want. For example, in a next post, I will show how to post a message to Yammer from SharePoint Online. When I will have such a feature I won't need the "What are you working on?" input zone any longer. So I have to find a way to embed my Yammer feed without using Yammer Embed to hide this zone.<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">3.1 Creating a Yammer App</span><br />
<br />
To program for Yammer using the SDK and the REST API, first you have to create a Yammer APP. The Yammer APP will:<br />
<ul><li>provide you with a Client Id that you will use in your SharePoint page code.</li>
<li>register your SharePoint page within Yamer to avoid the problem of cross-domain requests (CORS), because, even in an Office 365 integrated environment, you will notice that the SharePoint Online hostheader, and the Yammer hostheader are different . For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. Thus you cannot request the Yammer Web Services from a SharePoint Online page using client side code and XMLHTTPRequest. However, using a Yammr App will allow you to do that using the Yammer SDK.</li>
</ul><br />
So, let's create the Yammer App. Go to Yammer and locate the APPS menu and click it.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKVdZoFhX5fzCf_od1OWKcVuhRQSLQfPeFJx8pvwAhX4KFzhSUXthvelVsTyoncpwHa-p9MMhqvVCK-HrNZgQvMfLcoWnzVzlPW4fnJL6TPcSor01ww6Tj6XLqlmrPAoOPPO38PbA5EuCa/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+01+-+Yammer+-+Site+Contents.png+APPS+menu.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKVdZoFhX5fzCf_od1OWKcVuhRQSLQfPeFJx8pvwAhX4KFzhSUXthvelVsTyoncpwHa-p9MMhqvVCK-HrNZgQvMfLcoWnzVzlPW4fnJL6TPcSor01ww6Tj6XLqlmrPAoOPPO38PbA5EuCa/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+01+-+Yammer+-+Site+Contents.png+APPS+menu.png"></a><br />
<br />
You land on the Apps Directory page. Locate the "My Apps" button and click on it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoo8YVHAGjrA1zDUPSbkGgFEsaWwnNJx2zckAk6yZulDyThzKvJ_2iD_AjJ9MGyIhOjv27sc_CNd6gPbZ12njgZ6koZmZInH5t3DqwpmTomZTj2U2tM8HR2L30ZtG_0OAPNMl1oC1RwiqI/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+02+-+Yammer+-+Site+Contents+Apps+directory.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoo8YVHAGjrA1zDUPSbkGgFEsaWwnNJx2zckAk6yZulDyThzKvJ_2iD_AjJ9MGyIhOjv27sc_CNd6gPbZ12njgZ6koZmZInH5t3DqwpmTomZTj2U2tM8HR2L30ZtG_0OAPNMl1oC1RwiqI/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+02+-+Yammer+-+Site+Contents+Apps+directory.png"></a><br />
<br />
You land on the "Registered Applications" page. Here you can click the "Register New App" button to create your Yammer App. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYdfbWvi_woB1MvaGxspV1SHAArNCZmxiViYI58bEH51QzAfGuq0r7PpMfbr5TGz88q_rwBYj3euTxpT8G34g3KVZ0nl0fdnEs34_f4S6ysC6M5Hs925mSC2D_HHtBQmrLlKox3Y_-zR5W/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+03+-+Yammer+-+Registered+applications.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYdfbWvi_woB1MvaGxspV1SHAArNCZmxiViYI58bEH51QzAfGuq0r7PpMfbr5TGz88q_rwBYj3euTxpT8G34g3KVZ0nl0fdnEs34_f4S6ysC6M5Hs925mSC2D_HHtBQmrLlKox3Y_-zR5W/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+03+-+Yammer+-+Registered+applications.png"></a><br />
<br />
The registration Form is displaying. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFbEbc_a9Hn40VxJVvGi7FvY14k-De3dl1K_bjYekc9qlUpiwvdsirEBl_cCQD6BKeLUhxluuc46E7_FtG5xRU8epVn3veDOu8mFGP27UFnBUvbjPchx5Dj-F3jTtZ5xxy9-fG0l8BdRX9/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+04+-+Yammer+-+Registering+a+new+Yammer+App.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFbEbc_a9Hn40VxJVvGi7FvY14k-De3dl1K_bjYekc9qlUpiwvdsirEBl_cCQD6BKeLUhxluuc46E7_FtG5xRU8epVn3veDOu8mFGP27UFnBUvbjPchx5Dj-F3jTtZ5xxy9-fG0l8BdRX9/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+04+-+Yammer+-+Registering+a+new+Yammer+App.png"></a><br />
<br />
Here is an explaination regarding the settings: <br />
<br />
<ul><li>Application Name : chose an explicit name. In my case, it is a Yammer App to display a Yammer feed into a SharePoint Online Page.</li>
<li>Organisation : the one of your Office 365 environment</li>
<li>Website : the website that will host the page with the new App information (Client ID) for requesting the Yammer REST API. In my case, https://contososoftware.sharepoint.com/sites/intranet</li>
<li>Redirect Url : the website that will host the page with the new App information (Client ID) for requesting the Yammer REST API + "/oauth/callback". In my case : https://contososoftware.sharepoint.com/sites/intranet/oauth/callback</li>
</ul><br />
Then, click on the "continue" button for creating the new Yammer App, but it is not finished yet. <span style="background-color:yellow"> An important thing to do is to define the JavaScript Origin for the New Yammer App.</span> This is one of the important settings that is needed by Yammer to manage the concern of the HTTP Access Control (CORS). Roughly explained: Yammer needs to know the domain that will request its REST API using the client side code of a web page to tell the browser that a cross domain request is permitted. <br />
So, when your Yammer App is created, click on its name to open the page gathering its informations and settings. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMVxu6Rmcz1EnYwC8PAbTbyAf4K0Qhvlzhsgsl6m2_lY4ODk2WZf2RzGlwSjRQ9YsFu-Yc83u9CVkRJyemNBNS18qeIikwWdc5iAk8A7hHRlIAe6QNpFU2Y4EiM-NGQvclbo5F9Kbj2EV7/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+05+-+Yammer+-+new+Yammer+App+created.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMVxu6Rmcz1EnYwC8PAbTbyAf4K0Qhvlzhsgsl6m2_lY4ODk2WZf2RzGlwSjRQ9YsFu-Yc83u9CVkRJyemNBNS18qeIikwWdc5iAk8A7hHRlIAe6QNpFU2Y4EiM-NGQvclbo5F9Kbj2EV7/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+05+-+Yammer+-+new+Yammer+App+created.png"></a><br />
<br />
You will notice that one of the informations is the client ID that you will have to reference within the code of your web page when programming. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1dqgyGUb1VEC09lhla2SS_itfrk2D2jH_AwzEth_Kv2G3VSZ-uPPxItD-G7iSuERMsMcff5kJsdkJb9DEmRcPxmwBnOOr1PNpMHqnJ4SlLV2NTt0c_rcyYAH25qtFQit91cMvPnGz1jL5/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+06+-+Yammer+-+new+Yammer+App+created.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1dqgyGUb1VEC09lhla2SS_itfrk2D2jH_AwzEth_Kv2G3VSZ-uPPxItD-G7iSuERMsMcff5kJsdkJb9DEmRcPxmwBnOOr1PNpMHqnJ4SlLV2NTt0c_rcyYAH25qtFQit91cMvPnGz1jL5/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+06+-+Yammer+-+new+Yammer+App+created.png"></a><br />
<br />
Then, click the "Basic Info" link in the left menu. On the opening page, locate the "JavaScript Origin" input area, and type domain of the SharePoint Online site that will host the page that will request the Yammer RET API client side. In my case https://contososoftware.sharepoint.com<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5g6lEHgCbvbfTRzpawK_xj8_U3v1pj6gM24OOHnOEkL0SWS2Ihk4zPhqho2feCplno4vnvQwyy0h-om-md6GBhDlGk-8Hh36i_gQpMUQnS7Bz4TtvrECL3YHaXa4s7ibZyP2F0DtWZOfy/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+07+-+Yammer+-+Registering+a+new+Yammer+App+Javascript+Origin.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5g6lEHgCbvbfTRzpawK_xj8_U3v1pj6gM24OOHnOEkL0SWS2Ihk4zPhqho2feCplno4vnvQwyy0h-om-md6GBhDlGk-8Hh36i_gQpMUQnS7Bz4TtvrECL3YHaXa4s7ibZyP2F0DtWZOfy/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+07+-+Yammer+-+Registering+a+new+Yammer+App+Javascript+Origin.png"></a><br />
<br />
When all this is done, we can start programming the SharePoint page...<br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">3.2 Programming the SharePoint page for displaying the custom Yammer feed</span><br />
<br />
Now we are going to create the web page that will request the Yammer REST API. It will be a simple html page. When this page will be programmed, displaying the Yammer feed, we will display the custom yammer feed in a SharePoint Web Part page using an Iframe. <br />
So let's create the yammer-app.html page. <br />
<br />
Go to SharePoint Online Intranet, navigate to the site contents, then to the "Site Assets" library. In the "Library" tab of the Ribbon locate the "open with explorer" Ribbon. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbjCwTrOecIVnZvGsq26hhRRSz6MKX-ZW15M4v3OE9XzmHAhTcjAuWjL5UukXbiGg5Uye88Lc0fPjVlVlwqLYQfwQq8iT-c9iLYUIO6k1aAKH47RIqwAVF4Awe2eHa72ngRoHyeJ400kV4/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+95+-++Using+JavaScript+code+linbrary+-+Open+in+window+explorer.jpg" imageanchor="1"><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbjCwTrOecIVnZvGsq26hhRRSz6MKX-ZW15M4v3OE9XzmHAhTcjAuWjL5UukXbiGg5Uye88Lc0fPjVlVlwqLYQfwQq8iT-c9iLYUIO6k1aAKH47RIqwAVF4Awe2eHa72ngRoHyeJ400kV4/s1000/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+95+-++Using+JavaScript+code+linbrary+-+Open+in+window+explorer.jpg"></a><br />
<br />
It takes a little time and you have sometimes two warning pop-ups to close until the explorer open and show the SharePoint files. You can then navigate up to the root folder of your intranet site. And you can create a new file (let's say a text document).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6_UPOgS926mkein85eyKKMJ_XD_h5uaZNh-A008dYSGF7MWUVvTIh0vCmDkhPz6rcIVb-YmMWNFUPZf0P_HOctNybpioOUWHDD1sIvU8SY0O6xsyi-v0LZ803KJwMWOowhB3b7dZH0VdM/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+13+-+Site+Assets+-+adding+an+html+page.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6_UPOgS926mkein85eyKKMJ_XD_h5uaZNh-A008dYSGF7MWUVvTIh0vCmDkhPz6rcIVb-YmMWNFUPZf0P_HOctNybpioOUWHDD1sIvU8SY0O6xsyi-v0LZ803KJwMWOowhB3b7dZH0VdM/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+13+-+Site+Assets+-+adding+an+html+page.png"></a><br />
<br />
Then, you can rename the text document into "yammer-app.html". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicOh3ynLfRJvgTv4ibn6xUiBRIUdQUyV5NjuLFRiKzYl-OJlrUcz1LVaFzsUqDf-p1q8gXyGxVnxGuVG_R5YIs5XMj7JSJRjTK96eme-5gXagbfkbxcgNut0JSdZxpJK64vF3rhpfB9eCi/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+14+-+Site+Assets+-++html+page+added.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicOh3ynLfRJvgTv4ibn6xUiBRIUdQUyV5NjuLFRiKzYl-OJlrUcz1LVaFzsUqDf-p1q8gXyGxVnxGuVG_R5YIs5XMj7JSJRjTK96eme-5gXagbfkbxcgNut0JSdZxpJK64vF3rhpfB9eCi/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+14+-+Site+Assets+-++html+page+added.png"></a><br />
<br />
And for programming the page you can open it with Notepad ++ or even Visual Studio. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBo2oie8RbUWFwVfnNVjfAmq7zeozZnYs9R5e7MR3PsRVfdT-484KWFP_-hC8nNdLRuQUMYvEsJNZ-zseDcaFdKtgYAi5qrgukZTfXGl3imMwqBn1e47XKAtJq7rgOcy9NSi5I9TxbW4Vg/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+15+-+Site+Assets+-+editing+the+html+page.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBo2oie8RbUWFwVfnNVjfAmq7zeozZnYs9R5e7MR3PsRVfdT-484KWFP_-hC8nNdLRuQUMYvEsJNZ-zseDcaFdKtgYAi5qrgukZTfXGl3imMwqBn1e47XKAtJq7rgOcy9NSi5I9TxbW4Vg/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+15+-+Site+Assets+-+editing+the+html+page.png"></a><br />
<br />
<span style="background-color:yellow">You can find the complete code of the yammer-app.html page</span><a href="https://github.com/MarcCharmois/Embed-Yammer-into-SharePoint-Online" > within the dedicated GitHub repositery</a>, but here are the key points to understand the code: <br />
<ul><li>First, load the Yammer SDK while passing your Yammer App Client ID <br />
<br />
<div style="margin-left:10px;color:black"><script> type="text/javascript" data-app-id="aMqiweJ1Co7RQJkHX6TFg" src="https://c64.assets-yammer.com/assets/platform_js_sdk.js"></script></div><br />
</li>
<li>Second, you musn't call the Yammer web services directly using an Ajax request. <br />
You call the Yammer REST API with the "yam" object. Examples :<br />
<br />
triggering the authentication Pop-up if the user click the Yammer login button<br />
<br />
<div style="margin-left:10px;color:black">yam.connect.loginButton('#yammer-login', function (resp) {<br />
if (resp.authResponse) {<br />
//User is logged<br />
// do stuff<br />
}<br />
});</div><br />
calling Yammer to get the messages of a Yammer group<br />
<br />
<div style="margin-left:10px;color:black;">yam.platform.request(<br />
{ <br />
url: "https://api.yammer.com/api/v1/messages/in_group/6574317.json" //replace the group ID with your<br />
, method: "GET"<br />
,success: function (data) { <br />
//process the Yammer feed data...<br />
},<br />
error: function (msg) { alert("error getMyFeed ajax : " + msg.value); }<br />
})</div></li>
</ul><br />
Last, when your yammer-app.html page is working properly, you have finally to display the custom Yammer feed via a script editor Web Part into a SharePoint Web Part Page, or a SharePoint page customized via an Iframe tag: <br />
<div style="margin-left:10px;color:black;"><br />
<iframe style="height:500px;overflow:visible;" scrolling="no" src="https://contososoftware.sharepoint.com/sites/intranet/yammerapp.html"></iframe> <br />
</div><br />
<div class="alert"><table><tbody>
<tr><th align="left"><strong>Note</strong></th></tr>
<tr><td><p>Note that the messages/in_group/6574317.json web service is maybe not the best one for displaying messages. I read some posts that tell it doesn't retrieve all the messages. It seems that this web service has been removed from the Yammer documentation. I let you go to <a href="https://developer.yammer.com/docs/messagesjson">the Yammer documentation</a> and find the best web service for retrieving the messages depending on your needs...</p><p><br />
</td></tr>
</tbody></table></div><div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">4 - Regarding the Yammer authentication</div><br />
It' seems there is a way to enable Single Sign On (SSO) from SharePoint Online to Yammer so as the users authenticated on SharePoint Online don't have to authenticate another time while wanting to access to Yammer. <br />
I didn't try to enable the SSO yet on my trial environment, thus when a user of my environment land on the SharePoint page displaying the custom Yammer Embed feed, I have developped the presence of the Yammer Login Button. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNBQXJYQ5rUK_XzPG_PjRhZuALZKayJNansYMWx7hnYxkNXHRMTfHRdqdJK0NfDVQcQ_uWpliUGrAjPp6voPXcU66bDbTcLQ0pQVzd-H7WT-JR7J2xXb5oBJ0CvGdmQ_utgkNfh6bLskC/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+24+-+SharePoint+Online+authentication+Yammer+custom+feed.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNBQXJYQ5rUK_XzPG_PjRhZuALZKayJNansYMWx7hnYxkNXHRMTfHRdqdJK0NfDVQcQ_uWpliUGrAjPp6voPXcU66bDbTcLQ0pQVzd-H7WT-JR7J2xXb5oBJ0CvGdmQ_utgkNfh6bLskC/s1000/Get+feed+from+Yammer+-+Marc+Charmois+-+24+-+SharePoint+Online+authentication+Yammer+custom+feed.png"></a><br />
<br />
For displaying the Yammer custom Embed feed, the user has to click the Yammer Login button, and has to authentify. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9vmaUZVMwqhNyzBFlQDd_9I1t7Hp9ouJyupQKnV9KYbpxIk6yiWa6UUKBpVKHGkiL5lNoXpKjPXjRAJE_tQ1GJ1kJkbVBFFrVbeLhFeYOI6WT1ip_7Z2ItQjNcJYZLS1S_am9SKkM43hs/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+26+-+SharePoint+Online+authentication+Yammer+custom+feed+03.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9vmaUZVMwqhNyzBFlQDd_9I1t7Hp9ouJyupQKnV9KYbpxIk6yiWa6UUKBpVKHGkiL5lNoXpKjPXjRAJE_tQ1GJ1kJkbVBFFrVbeLhFeYOI6WT1ip_7Z2ItQjNcJYZLS1S_am9SKkM43hs/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+26+-+SharePoint+Online+authentication+Yammer+custom+feed+03.png"></a><br />
<br />
Then, the custom Yammer Embed feed is displaying. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOweiRifFRSTuWbzqn6oOYYthifZ0hABrDmOyYq-T0UMlVchV9MMGEWPuJgHTsaWRoWKS1AaVZ_GL1IJF1MeKUqAUQCZpw1XTfKPGdn_i4S90faQF0ILj38B8OdFEhYt4O9BdSfEYBvsfT/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+27+-+SharePoint+Online+authentication+Yammer+-+User+authentified.png" imageanchor="1" ><img class="screenshot-standard" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOweiRifFRSTuWbzqn6oOYYthifZ0hABrDmOyYq-T0UMlVchV9MMGEWPuJgHTsaWRoWKS1AaVZ_GL1IJF1MeKUqAUQCZpw1XTfKPGdn_i4S90faQF0ILj38B8OdFEhYt4O9BdSfEYBvsfT/s1600/Get+feed+from+Yammer+-+Marc+Charmois+-+27+-+SharePoint+Online+authentication+Yammer+-+User+authentified.png"></a><br />
<br />
In my environment, if the user is refeshing the page, he doesn't have to authentify again, but in my company and in my client Office 365 environments, when refreshing the page, the user HAS to authentify again.<br />
There is a way to avoid this. You have to store the Yammer oauth token and reuse it when the page is refreshing.<br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">4.1 Storing the Yammer oauth token to reuse it</span><br />
<br />
When the user is authentified you store the token in the localStorage property that is compliant with most of the browsers. It is an amazing way to simulate the session variables. <br />
<div style="margin-left:10px;color:black">
<pre class="code-standard">yam.connect.loginButton('#yammer-login', function (resp) {
if (resp.authResponse) {
localStorage.setItem(1, JSON.stringify(resp.access_token.token).replace(/"/g, ""));
console.log("token" + localStorage.getItem(1));
//Hiding the login button because the user is logged in
document.getElementById('yammer-login').style.display = 'none';
}
});
</pre></div><br />
Now, when the page is refreshing, there is a way to test if the user is logged or not using the JavaScript SDK of Yammer: <br />
<br />
</div>
<div style="margin-left:10px;color:black">
<pre class="code-standard">yam.getLoginStatus( function(response) {
if (response.authResponse) {
//user is logged in
//nothing to do
} else {
//check if a oauth token is stored for this user
//if yes,
//reload the custom Yammer Embed feed and use the oauth token stored in local storage to authentify the request
}
});
</pre>
</div><br />
Finally, here is the correct syntax to pass the bearer token to yammer while loading a feed usinf the JavaScript SDK:<br />
<br />
<div style="margin-left:10px;color:black">
<pre class="code-standard">
function getMyYammerFeed(){
document.getElementById("yammer-feed").innerHTML="<img src='/sites/portail-dircom/PublishingImages/ajax-loader1.gif' style='margin-top:100px;margin-left:95px;' />";
var tokenToSend = "Bearer " + localStorage.getItem(1);
console.log("authorization bearer : " + tokenToSend);
yam.platform.request(
{
url: "https://api.yammer.com/api/v1/messages/in_group/6572783.json"
,method: "GET"
,beforeSend: function (xhr){xhr.setRequestHeader('Authorization', tokenToSend)}
,success: function (data) {
try{
//process the feed datas
}catch(error){alert("error getMyFeed process : " + error); }
},
error: function (msg) { alert("error getMyFeed ajax : " + msg.value); }
}
)
}
</pre>
</div><br />
<br />
<br />
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com6tag:blogger.com,1999:blog-4357140756496246910.post-28354788012870209472015-10-16T21:55:00.000+02:002019-09-05T17:30:32.341+02:00Branding a SharePoint Online team site using the SharePoint JavaScript Object Model
<div class="h2-paragraph">
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">In this post I will show how to use the JavaScript library code (JavaScript Client Object Model: SP.Runtime.js and SP.js) for easily branding a SharePoint Online team site while respecting the new pattern and practices. This is a third approach compared with the two ones currently recommended by Microsoft for SharePoint Online, that is to mean: <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">NCSSs versus Add-Ins</a>.<br />
<br />
I will show in the following tutorial <span style="background-color:yellow">how to easily perform some of the main operations done by the Add-in while avoiding most of the Add-In way complications</span>.<br />
<br />
For a complete round regarding the classical approaches, you can visit this post: <a href="http://mosshowto.blogspot.fr/2015/10/sharepoint-online-branding-team-site.html">Branding a SharePoint Online Team Site</a><br />
You can also read this post that gives a more accurate overview of the recommendations: <a href="http://www.microsofttrends.com/2015/05/07/latest-advice-on-office-365-branding/">Latest Advice on Office 365 Branding</a>.<br />
<br />
<a href="http://3.bp.blogspot.com/-xsV_O4RtUXA/ViEDKnAKWII/AAAaAAAAALM4/j0usNpbglaE/s1600/Branding%2BSharePoint%2BOnline%2Bteam%2Bsite%2Busing%2BJavaScript%2BCode%2BLibray%2B01%2Bfinal%2Bresult.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXLYN1Z-qZ7IsKLhSRkczbCQUnYEKa5eHH5BZcmp0Ev6ehzcJzzq73kEXUqehkCBXmJulrILAm6isMQz_Tb6bR6CVJNcZQrI-5Y-IagA_VbngMoa-_EAE6uKp6vt2MfyOseYZEbpNi-Igq/s1000/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+01+final+result.jpg" class="screenshot-standard" ></a><br />
<br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">1 - Add-ins versus NCSSs</div><br />
If you read carefully the <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">MSDN documentation (updated August 2015 the 12th)</a> exposing the recommendations regarding the use of the No-Code Sandboxed Solution or NCSS (aka a .wsp containing no server code and deployed in the Solution store at the Site Collection level), versus the use of the SharePoint Add-Ins (formerly called Apps for SharePoint), you can summarize it with the following conclusions: <br />
<br />
Microsoft recommends to use Add-Ins whenever you can, but recommends NCCSs for branding as the easiest way to do it.<br />
<br />
Regarding the Add-In approach, you can already review the material available on the Office 365 Developer Patterns and Practices: <br />
<br />
<a href="https://channel9.msdn.com/Blogs/Office-365-Dev/Alternate-CSS-and-set-site-logo-Office-365-Developer-Patterns-and-Practices">Video on Channel 19: Alternate CSS and set site logo</a><br />
<br />
<a href="https://github.com/OfficeDev/PnP/tree/master/Samples/Branding.AlternateCSSAndSiteLogo">Associated source code for the Add-In available on GitHub</a><br />
<br />
You will notice that in the Office 365 Developer Patterns and Practices sample, the Add-In :<br />
<ul><li>Change programmatically (Imperative approach) the logo and the CSS references for the site<br />
<br />
web.AlternateCssUrl = web.ServerRelativeUrl + "/SiteAssets/contoso.css";<br />
web.SiteLogoUrl = web.ServerRelativeUrl + "/SiteAssets/pnp.png";<br />
web.Update();<br />
web.Context.ExecuteQuery(); <br />
<br />
</li>
<li>Upload programmatically (Imperative approach) the logo and the CSS files for the site<br />
<br />
// Use CSOM to upload the file in<br />
FileCreationInformation newFile = new FileCreationInformation();<br />
newFile.Content = System.IO.File.ReadAllBytes(cssFile);<br />
newFile.Url = "contoso.css";<br />
newFile.Overwrite = true;<br />
Microsoft.SharePoint.Client.File uploadFile = assetLibrary.RootFolder.Files.Add(newFile);<br />
web.Context.Load(uploadFile);<br />
web.Context.ExecuteQuery();<br />
<br />
// Get the path to the file which we are about to deploy<br />
string logoFile = System.Web.Hosting.HostingEnvironment.MapPath(<br />
string.Format("~/{0}", "resources/pnp.png"));<br />
<br />
// Use CSOM to upload the file in<br />
newFile = new FileCreationInformation();<br />
newFile.Content = System.IO.File.ReadAllBytes(logoFile);<br />
newFile.Url = "pnp.png";<br />
newFile.Overwrite = true;<br />
uploadFile = assetLibrary.RootFolder.Files.Add(newFile);<br />
web.Context.Load(uploadFile);<br />
web.Context.ExecuteQuery();<br />
</li>
</ul><br />
Then you can figure out the pros and the cons of these two approaches: <br />
<br />
<b>Add-Ins: </b><br />
<ul><li>The pros <br />
<ul><li><span style="color: red;">no impacts regarding Microsoft updates</span>:<br />
As Add-Ins are using imperative approach (doing things programmatically) the OOTB templates of SharePoint (Web Part Page Templates, Page Layouts, default.aspx page, Master Pages) are preserved so as any update from Microsoft regarding these templates will have no impacts on the customizations performed using Add-Ins. That is to mean: <span style="color: red;">no custom Master Page anymore, no CAML anymore, ever!</span><br />
</li>
<li>The branding action could be perform by a super user:<br />
It seems that you can leverage the permission for the users just for the use of the Add-In so as the users to be able to activate the branding of a site themselves without belonging to the Site Collection Administrators.<br />
</li>
</ul></li>
<li>The cons <br />
<ul><li><span style="color: red;">NCSSs are more powerful</span>: <br />
As Add-Ins are using imperative approach (doing things programmatically) and NCSSs can use both imperative (Client side of course with <a href="https://msdn.microsoft.com/en-us/library/office/jj163201.aspx">SharePoint JavaScript library code</a>) and declarative approach (modifying HTML, CSS within the custom templates and CAML for deploying and registering these custom templates in the libraries), <span style="color: red;">there are numerous things that you can do with NCSSs that you cannot do using Add-Ins. That is to mean: custom Master Pages, custom pages, with all the HTML and the server controls you want within the custom pages</span>. <br />
</li>
<li>Add-Ins require more time and more knowledge: <br />
Add-In model is completely new and different from classical approaches, thus technical team will have to enhance knowledge to be really comfortable with these new approaches. As said in the MSDN documentation when using Add-Ins remote imperative approach "it would take a considerable amount of work to create this code".<br />
Not only the SharePoint team will be involved, but also people working in the infrastructure and network areas because setting the necessary things regarding network and authentication for getting Add-ins work properly in a company requires also time and knowledge. <br />
</li>
</ul></li>
</ul><b>No-Code Sandboxed Solutions (aka NCSSs):</b><br />
<ul><li>The Pros<br />
<ul><li>Although the new Add-Ins model for SharePoint (formerly called Apps) is documented by Microsoft as the the recommended way for customizing SharePoint, you can see in <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">the official MSDN documentation</a> that among the scenarios recommended by Microsoft for using No-Code Sandboxed Solutions instead of Add-Ins (formerly called Apps), Branding of SharePoint Sites is one of them:<br />
<br />
[... SharePoint users often want to give their SharePoint sites, including their SharePoint Online sites, a custom appearance with their own colors, styles, layouts, and logos. This is generally easier to do with NCSSs than with SharePoint Add-ins.<br />
...] MSDN <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx#Anchor_2"> SharePoint Add-ins compared with SharePoint solutions</a><br />
<br />
But NCSSs compared with Add-Ins are not only an easier way for branding a SharePoint Online site. Regarding branding, Add-Ins are more limited: <br />
<br />
[...<br />
A SharePoint Add-in has declarative control over the appearance of only its own add-in web. For the host web, it can declaratively add only ribbon buttons and menu items (and add-in parts). Any other changes to a host web or its parent site collection, tenancy, or on-premisesSharePoint web application has to be done with code or script that uses one of the SharePoint's client object models. For example, new icons or CSS files would have to be programmatically deployed. This code could be run from the add-in itself after it is installed, or it could run in the add-in installation event handler. But it would take a considerable amount of work to create this code. <br />
In addition, the add-in would need site collection-scoped permissions to change any websites outside its own add-in web and host web, and it would need tenant-scoped permissions to change more than just its parent site collection. A branding NCSS, however, can be deployed and activated to any site collection; and it could consist of only a few purely declarative components.<br />
...] (<a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx#Anchor_2">MSDN</a>)<br />
</li>
</ul></li>
</ul><ul><li>The Cons </li>
<ul><li>As your customized pages are not based on a OOTB SharePoint template anymore, <span style="color: red;">if any update of the SharePoint templates is performed by Microsoft</span>, these updates won't be taken into account by your customized page. <span style="color: red;">You will miss new features of the product or maybe even lose current ones depending on the Microsoft updates.</span> So you might perform sometimes unexpected maintenance operations for recovering all the features of the SharePoint product. (<span style="color: red;">it might not be the case with custom master pages based on the use of the Design Manager with which you can convert an.html file into a SharePoint 2013 master page, a .master file</span>. I have to check this more seriously. By the way, I planned to redo the same post using the SharePoint Publishing Features).<br />
</li>
<li>Using NCSS for branding a SharePoint Online team site will require the privileges of Site Collection Administrator and cannot be performed by a super user. <br />
</li>
</ul></ul><div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">2 - A third approach: using JavaScript Object Model within a Site Page</div>I will show in the following tutorial how to easily perform some of the main operations done by the Add-in while avoiding most of the Add-In way complications. We will : <br />
<ul><li>Upload the new logo of the site manually<br />
</li>
<li>Upload the new css of the site manually<br />
</li>
<li>Create the page for branding the site manually<br />
</li>
<li>Add Javascript code to the page in order to change automatically, the Logo, the css and the Master Page of the site. <br />
</li>
</ul><br />
<span style="color: #e9ab17; margin-left: 50px;">2.1 Upload the new logo of the site manually</span><br />
<br />
Use Bing or Google images to find a logo of the Contoso company. Try to find one based on a .gif or a .png with transparency (Contoso-Blue.png is fine). <br />
When it's done, go to the SharePoint Online team site you want to customize (<a href="https://www.microsoft.com/en-us/evalcenter/evaluate-office-365-proplus">you can easily get a trial environement for 30 days</a>). You need to be administrator of the Site Collection. <br />
Then, create a folder called "images" in the site collection "Style Library" and Upload the Contoso logo image in the folder.<br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX4UksMg89lrDfIqyqgU5h7yk2EFt4UMwVQJgWeW9GjXT5JDSK3M84leYLUHH1Xm-7U7zEBb5lHwvbp1pi7aH5EHh3Wo_1kH1N_kO_-sEchQMnUxSQ5BsnQ1JDv0BwjRCXy1AUUpUDtdDT/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+88+-++Using+JavaScript+code+linbrary+-+Home+Page.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX4UksMg89lrDfIqyqgU5h7yk2EFt4UMwVQJgWeW9GjXT5JDSK3M84leYLUHH1Xm-7U7zEBb5lHwvbp1pi7aH5EHh3Wo_1kH1N_kO_-sEchQMnUxSQ5BsnQ1JDv0BwjRCXy1AUUpUDtdDT/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+88+-++Using+JavaScript+code+linbrary+-+Home+Page.jpg" class="screenshot-standard" ></a></div><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzDB0B6rreJHgCw9i29TfNr1LFxhSYjLE8-szCS0WAvKiZic14WUHsGYSYRs6xOpX4ZetAWylToG3u_uVEdVTNnMS4IPbyXVG3PBvT4F3VR0DZBEY0kGoz2ys12TaCEjv9MpS3QeI26G0N/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+97+-++Using+JavaScript+code+linbrary+-+images+folder+01.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzDB0B6rreJHgCw9i29TfNr1LFxhSYjLE8-szCS0WAvKiZic14WUHsGYSYRs6xOpX4ZetAWylToG3u_uVEdVTNnMS4IPbyXVG3PBvT4F3VR0DZBEY0kGoz2ys12TaCEjv9MpS3QeI26G0N/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+97+-++Using+JavaScript+code+linbrary+-+images+folder+01.jpg" class="screenshot-standard" ></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPug-myJ-QUebPLjLyn_-_kPb-G39GKHQE1XHz8V2SK9pmmWRe-HYOjT24inqrhUUakqhU8i_G_nqU6dUW1NbCyYAHgaPJcwb7ZVGPytI65e3IulYKTdFnVk32kRqVCadZdte4xYwwUhVX/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+98+-++Using+JavaScript+code+linbrary+-+checkin+logo+01.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPug-myJ-QUebPLjLyn_-_kPb-G39GKHQE1XHz8V2SK9pmmWRe-HYOjT24inqrhUUakqhU8i_G_nqU6dUW1NbCyYAHgaPJcwb7ZVGPytI65e3IulYKTdFnVk32kRqVCadZdte4xYwwUhVX/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+98+-++Using+JavaScript+code+linbrary+-+checkin+logo+01.jpg" class="screenshot-standard" ></a><br />
<br />
Don't forget to check in the logo image, in order visitors of the site will be able to see it. (if the logo image is checked out, only the administrator of the site will be able to see it).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTj6dm65hJN_RduQMmrz3ADsB5ciH8gWGVBufqezDXbP6f2wfY0HxZibAaqxMNL-PHOWVOO3dZE2TWWOulaayGxwR1ihvEQdwXnCZSv-435csMacNv6QM5KynvmhuTOUfrXSdGst6PRwUo/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+13+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTj6dm65hJN_RduQMmrz3ADsB5ciH8gWGVBufqezDXbP6f2wfY0HxZibAaqxMNL-PHOWVOO3dZE2TWWOulaayGxwR1ihvEQdwXnCZSv-435csMacNv6QM5KynvmhuTOUfrXSdGst6PRwUo/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+13+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" class="screenshot-standard" ></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghrnIrs5xOZJQnFlZaGjE603KCDyPnROitVRM6EkUvSqm_KJY4ifO4KrL2IcUTGoBYMMPUtwwgoUOMUU1J55mT6bWeydSwLo-WY1yXptVivF2HGBSthMza9nG8LXnWIjq_5lPR-dhCnhU8/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+14+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghrnIrs5xOZJQnFlZaGjE603KCDyPnROitVRM6EkUvSqm_KJY4ifO4KrL2IcUTGoBYMMPUtwwgoUOMUU1J55mT6bWeydSwLo-WY1yXptVivF2HGBSthMza9nG8LXnWIjq_5lPR-dhCnhU8/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+14+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" class="screenshot-standard" ></a><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">2.2 Upload the new css of the site manually</span><br />
<br />
Create a file called contoso.intranet.css and paste the following css within the file: <br />
<br />
#siteIcon{margin-top:0px;}<br />
#titleAreaBox{margin-top:0px;margin-left:20%;margin-right:20%;background-color:rgba(242, 242, 242, 1);}<br />
#titlerow{background-color:rgba(242, 242, 242, 1);}<br />
.ms-core-listMenu-horizontalBox{margin-top:30px;margin-left:-200px;}<br />
.ms-breadcrumb-box {padding-top: 5px;padding-bottom: 5px;height:30px;}<br />
#SearchBox{margin-left:200px;margin-right:-50px;}<br />
#suiteBarDelta{margin:0px;margin-top:0px;}<br />
#DeltaPlaceHolderSearchArea{padding-top:45px;}<br />
.ms-srch-sb > input {width: 140px;}<br />
<br />
Then, create a folder called "css" within the site collection "Style Library", and Upload the file within the "css" folder. <br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHirrTfZSNBKZLuiktuhVbRkhx3jzF3oMAsgC575MqeNPxbcaWR-87-HPr-wXcaQu290_cm3YWYGwEwJiIayINMLCh5M1Ae4RJl4daB_Nf0NKDMFjj6eqnvA7aYOITP79lCRqHByA-yIJT/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+59+-+uploading+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHirrTfZSNBKZLuiktuhVbRkhx3jzF3oMAsgC575MqeNPxbcaWR-87-HPr-wXcaQu290_cm3YWYGwEwJiIayINMLCh5M1Ae4RJl4daB_Nf0NKDMFjj6eqnvA7aYOITP79lCRqHByA-yIJT/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+59+-+uploading+the+css+file+within+SharePoint+Online.jpg" class="screenshot-standard" ></a><br />
<br />
You can see that the .css file has been properly added within the folder, but it is checked out so only administrator will be able to see it. We have to check it in. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBlPFQrMTEA2pBzuMWASki6ScmG0Di-jF4Z8aYquqzFTg3F0GvQDgEZK5IlZZUCN8Afo_BD-W0UHTX6UWaHxVDqcF1Ee1cHCxFi04rq788c8cAKsdWqyE-jS0teJ5cah4OmNmM28yvKEu/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+61+-++checking+in+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBlPFQrMTEA2pBzuMWASki6ScmG0Di-jF4Z8aYquqzFTg3F0GvQDgEZK5IlZZUCN8Afo_BD-W0UHTX6UWaHxVDqcF1Ee1cHCxFi04rq788c8cAKsdWqyE-jS0teJ5cah4OmNmM28yvKEu/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+61+-++checking+in+the+css+file+within+SharePoint+Online.jpg" class="screenshot-standard" ></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoAjwOamOe4WD0K017DVvDj_b_PZiyp-_6Yo4rmU5PxCHGhhNT4X6lg3SDwUlab3Wg7I_LAECc3nU7gT4LVrgkorcMIm2ocya2IveECaHHErojhWb37BN5Ktdfy18n7nw57VcQXrVRr7mV/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+62+-++checking+in+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoAjwOamOe4WD0K017DVvDj_b_PZiyp-_6Yo4rmU5PxCHGhhNT4X6lg3SDwUlab3Wg7I_LAECc3nU7gT4LVrgkorcMIm2ocya2IveECaHHErojhWb37BN5Ktdfy18n7nw57VcQXrVRr7mV/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+62+-++checking+in+the+css+file+within+SharePoint+Online.jpg" class="screenshot-standard" ></a><br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">2.3 Creating the Site Page for branding the site</span><br />
<br />
Navigate to the "Site Contents" page of your SharePoint Online team site, and locate the "Site Pages" library. <br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnRhKF6JWO1suHSI1dYfO3JfD-MPYrZUoyBBBaigf0ct6tG9txFV9PSYaI4E5PuJg3TT0YNA-kfwLmbLFFLBF5pKJ4q0_WP8Er-qjORxY-S9KvTKURO9OSR23YJ6MS4rzT9pDHxlNsE8Hh/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+88+-++Using+JavaScript+code+linbrary+-+Site+Content.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnRhKF6JWO1suHSI1dYfO3JfD-MPYrZUoyBBBaigf0ct6tG9txFV9PSYaI4E5PuJg3TT0YNA-kfwLmbLFFLBF5pKJ4q0_WP8Er-qjORxY-S9KvTKURO9OSR23YJ6MS4rzT9pDHxlNsE8Hh/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+88+-++Using+JavaScript+code+linbrary+-+Site+Content.jpg" class="screenshot-standard" ></a></div><br />
Open the Site Pages library and start creating a new Web Part page. <br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnKtSjENDNESPwuRcy1knZ8s7HKD5GIKWd3bbAJKwDRLRj0u5X3FaOZ-Y6m6c3YvVVmKCmAzV2oFVr4nK5fQowq79Wsv1gK70bnwakupbL6pBpEdT_90P5d2gZoKYSsW6hN2KOy_CKczTX/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+90+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnKtSjENDNESPwuRcy1knZ8s7HKD5GIKWd3bbAJKwDRLRj0u5X3FaOZ-Y6m6c3YvVVmKCmAzV2oFVr4nK5fQowq79Wsv1gK70bnwakupbL6pBpEdT_90P5d2gZoKYSsW6hN2KOy_CKczTX/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+90+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page.jpg" class="screenshot-standard" ></a></div><br />
Call the page "Brand this Site"<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheeLrtHhR4dFvDGOuHW7S49Kz3t_lqYoNm1-P6EsTNXed9jEsIutkL7Qsa8jNdP_frxuzGCFJAcPQQPjvOqy59VD2OMzMwQvxOTsK3uhDECmj_P8s06ijldGxbhIQfXFO3cb7skOvf553h/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+91+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+02.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheeLrtHhR4dFvDGOuHW7S49Kz3t_lqYoNm1-P6EsTNXed9jEsIutkL7Qsa8jNdP_frxuzGCFJAcPQQPjvOqy59VD2OMzMwQvxOTsK3uhDECmj_P8s06ijldGxbhIQfXFO3cb7skOvf553h/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+91+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+02.jpg" class="screenshot-standard" ></a><br />
<br />
The page appears in "edited" mode <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_CwPJXgcKFL_yFXG_V7sX6F0pA-wY0fYW9-Yxk0pe9ZHMNb0aqnPpEWjGEN1ChVEE3Wz7ugJ4NxF8MxyRp4ev9a_Im1eSxJkEqU-jZxCGG8-vIx4o_nbjE7GXeRmcJuL57f1YbMLbdJ6N/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+91+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_CwPJXgcKFL_yFXG_V7sX6F0pA-wY0fYW9-Yxk0pe9ZHMNb0aqnPpEWjGEN1ChVEE3Wz7ugJ4NxF8MxyRp4ev9a_Im1eSxJkEqU-jZxCGG8-vIx4o_nbjE7GXeRmcJuL57f1YbMLbdJ6N/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+91+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created.jpg" class="screenshot-standard" ></a><br />
<br />
Stop editing the page and note that the page was unexpectedly created within the "Site Assets" library. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Fewy3AUF9073qUadSATDfuFhwsdKOTWojpzWvx7849t3W1ep9LHIO78HUm445sOTmO5yllA0vYlno8yrmaUpPBfBrP7CKCKrWlJ8DcPwPAooUzBzZe70Lk4OM74ebG2MlM5hve48gXZa/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+93+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created+02.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Fewy3AUF9073qUadSATDfuFhwsdKOTWojpzWvx7849t3W1ep9LHIO78HUm445sOTmO5yllA0vYlno8yrmaUpPBfBrP7CKCKrWlJ8DcPwPAooUzBzZe70Lk4OM74ebG2MlM5hve48gXZa/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+93+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created+02.jpg" class="screenshot-standard" ></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOFSAZKWm1HTz_LRc4zYd04K83PjklL_RwEpZ1kLmnxLqu61iVpE2tBmCOi5vQXpQFiDOGZBnbrXtJ_OOkcnsfUMn-I9XNYEL73-8WSyPEMWw321wv9H-BJegy4Q6d4McbE3gKyl6NT0dz/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+94+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created+in+site+Asseets+library.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOFSAZKWm1HTz_LRc4zYd04K83PjklL_RwEpZ1kLmnxLqu61iVpE2tBmCOi5vQXpQFiDOGZBnbrXtJ_OOkcnsfUMn-I9XNYEL73-8WSyPEMWw321wv9H-BJegy4Q6d4McbE3gKyl6NT0dz/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+94+-++Using+JavaScript+code+linbrary+-+New+Web+Part+Page+created+in+site+Asseets+library.jpg" class="screenshot-standard" ></a><br />
<br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">2.4 Open the Site Page, using WebDAV protocol for modifying the source code</span><br />
<br />
Now we are going to edit the page source code using WebDAV protocol. This is perfectly allowed since you will see in the page properties something called "Open with Microsoft SharePoint Designer". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx_z9M0UUk4EFp4MCBdd0h-bzFy8yLQFQs0Se3Z0IAHhyphenhyphenUW4hww1tb8fgZx3sY4U1qCkMeAMY7YoeTxiSge_SDQFakCI1TBWlyzLpQE6LUtizLB5L158sZlRPNB38jhorpRKik9miKJbBg/s1600/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+105+open+the+%2527brand+the+site%2527+page+in+webDav+mode.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx_z9M0UUk4EFp4MCBdd0h-bzFy8yLQFQs0Se3Z0IAHhyphenhyphenUW4hww1tb8fgZx3sY4U1qCkMeAMY7YoeTxiSge_SDQFakCI1TBWlyzLpQE6LUtizLB5L158sZlRPNB38jhorpRKik9miKJbBg/s1200/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+105+open+the+%2527brand+the+site%2527+page+in+webDav+mode.jpg" class="screenshot-standard" ></a><br />
<br />
If you have SharePoint Designer you can now open the page with it. If not, I will show you a trick to edit the page source code using the webDAV protocol with Notepad++. (Note that for me, depending on the machines I am working on, sometimes, clicking on the link "Open with Microsoft SharePoint Designer" while not having SharePoint Designer installed on the machine, leads to open the file in WebDAV protocol within the Notepad!)<br />
<br />
Navigate to the Site Assets Library, and within the "Library" Tab of the Ribbon, locate the button called "Open With Explorer". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbjCwTrOecIVnZvGsq26hhRRSz6MKX-ZW15M4v3OE9XzmHAhTcjAuWjL5UukXbiGg5Uye88Lc0fPjVlVlwqLYQfwQq8iT-c9iLYUIO6k1aAKH47RIqwAVF4Awe2eHa72ngRoHyeJ400kV4/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+95+-++Using+JavaScript+code+linbrary+-+Open+in+window+explorer.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbjCwTrOecIVnZvGsq26hhRRSz6MKX-ZW15M4v3OE9XzmHAhTcjAuWjL5UukXbiGg5Uye88Lc0fPjVlVlwqLYQfwQq8iT-c9iLYUIO6k1aAKH47RIqwAVF4Awe2eHa72ngRoHyeJ400kV4/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+95+-++Using+JavaScript+code+linbrary+-+Open+in+window+explorer.jpg" class="screenshot-standard" ></a><br />
<br />
If you click on this button (be patient it takes time, and sometimes you have 2 warning pop-ups to close, and even to add the SharePoint Online domain in the trusted sites of your Internet Explorer) a Microsoft OS Explorer Window is opening where you can see the SharePoint files! (this is just amazing because actually the SharePoint files are stored, whether in the SharePoint content databases, or just as a link in the content databases pointing to the SharePoint server files system).<br />
Note that this only works with Internet Explorer. <br />
Now you can see the files within a Microsoft Explorer Window, you can as usual, right-click one of them, and choosing the option "Open with", open the file using WebDAV protocol with Notepad, Notepad++ or Visual Studio, or any HTML Code Source Editor of your choice. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiir_DKuHwvrFzlyTk014Vgv9fadyH5GKjIYEB5Q3wWlCTW2rr6NhvIc5jDN4mh6W5Zbd1Jt6dyXUJKL7OG2F5utGJh_Mekx1NfhbPAEtGx7pXdCNdf-ZmrdNV8QikUhoa1wxvreSkx4XfG/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+96+-++Using+JavaScript+code+linbrary+-+Open+file+in+Visual+Studio.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiir_DKuHwvrFzlyTk014Vgv9fadyH5GKjIYEB5Q3wWlCTW2rr6NhvIc5jDN4mh6W5Zbd1Jt6dyXUJKL7OG2F5utGJh_Mekx1NfhbPAEtGx7pXdCNdf-ZmrdNV8QikUhoa1wxvreSkx4XfG/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+96+-++Using+JavaScript+code+linbrary+-+Open+file+in+Visual+Studio.jpg" class="screenshot-standard" ></a><br />
<br />
<span style="color: #e9ab17; margin-left: 50px;">2.5 Add Javascript and HTML code to the page in order to change automatically, the Logo, the css and the Master Page of the site.</span><br />
<br />
Now we have to:<br />
<ul><li>Reference the JQuery Library.<br />
</li>
<li>Create the code to brand and of course, unbrand the site.<br />
</li>
</ul><br />
First, create a folder called "scripts" in the "Style Library" of the Site Collection and paste in it the jQuery-1.9.1.min.js. You can find this file within an Add'In (App) project created with Visual Studio. Any else jQuery library could be fine however, since we use just basic jQuery features in this tutorial code. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOLEUjylC7nSPHUu5KkJQDo9NvWYLFlt4G7X9AAo4esCtTXcQacIHa7mBYfoWVwrsaWDnDvRp2HUGjio-2O0rLQseIy45lnrLjf6JZ0fQIgoTWSvXuN-25_vrSM3M_D2XHKhDwhccUAryN/s1600/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+107+JQuery+file+within+the+SharePoint+Online+Style+Library.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOLEUjylC7nSPHUu5KkJQDo9NvWYLFlt4G7X9AAo4esCtTXcQacIHa7mBYfoWVwrsaWDnDvRp2HUGjio-2O0rLQseIy45lnrLjf6JZ0fQIgoTWSvXuN-25_vrSM3M_D2XHKhDwhccUAryN/s1200/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+107+JQuery+file+within+the+SharePoint+Online+Style+Library.jpg" class="screenshot-standard" ></a><br />
<br />
<span style="color:red">The complete source code of the brand-this-site.aspx Web Part Page and the .ccs file are available @</span> <a href="https://github.com/MarcCharmois/SharePoint_Online_Branding_JSOM">the dedicated GitHub repositery</a><br />
<br />
Within your .aspx page open in the code source editor with WebDAV protocol, locate the last meta tag at the beginning of the page within <b>"PlaceHolderAdditionalPageHead"</b> section:<br />
<br />
<span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">meta</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">name</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="CollaborationServer"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">content</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="SharePoint Team Web Site"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">/></span><br />
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">and ad the reference to the jQuery library. <br />
Be careful to point to the right location depending of your Site Collection and Site Name. In my case, here is the code of the section within Visual Studio:</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">meta</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">name</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="CollaborationServer"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">content</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="SharePoint Team Web Site"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">/></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> <</span><span style="background: white; color: darkgreen; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">!-- Added using WebDAV mode by Marc Charmois ---></span></div></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">type</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="text/javascript"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">src</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="/Sites/intranet2/Style%20Library/scripts/jquery-1.9.1.min.js"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: darkgreen; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><!--script type="text/javascript" src="/_layouts/15/sp.runtime.js"</script-->/script></span><br />
<span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: darkgreen; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><!--script type="text/javascript" src="/_layouts/15/sp.js"</script-->/script></span><br />
<span style="background: white; color: darkgreen; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><!-- end of the WeDAV customization --></span><br />
<span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">sharepoint</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">:</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">scriptblock</span><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">runat</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">="server"></span></div></div><div class="MsoNormal"><o:p></o:p>Notice that I used to reference the JSOM libraries, but I stopped since there are referenced in the Web Part page source code of SharePoint Online. <br />
<br />
Then, just below the <asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server"> opening tag, paste the JavaScript code and <span style="color: red; font-weight: bold;">replace the paths to the files with the ones corresponding to your SharePoint Online team site:</span><br />
<br />
<div style="border:solid 1px silver;width:100%;overflow:scroll;white-space:pre">
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">
<asp</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">:</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">Content</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">ContentPlaceHolderID</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="PlaceHolderMain"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">runat</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="server"></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">function</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> branding() {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">try</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">var</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> context = </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">new</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> SP.ClientContext.get_current();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">var</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web = context.get_web();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_masterUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'/sites/intranet2/_catalogs/masterpage/oslo.master'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_siteLogoUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'/sites/intranet2/Style%20Library/images/Contoso-Blue.png'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_alternateCssUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'/sites/intranet2/Style%20Library/CSS/Contoso.Intranet3.css'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.update();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> context.executeQueryAsync(onQuerySucceeded, onQueryFailed);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> } </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">catch</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> (error) {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> alert(error);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">function</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> unBranding() {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">try</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">var</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> context = </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">new</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> SP.ClientContext.get_current();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">var</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web = context.get_web();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_masterUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'/sites/intranet2/_catalogs/masterpage/seattle.master'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_siteLogoUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'/_layouts/15/images/siteIcon.png?rev=40'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.set_alternateCssUrl(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">''</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> web.update();<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> context.executeQueryAsync(onQuerySucceeded, onQueryFailed);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> } </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">catch</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> (error) {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> alert(error);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">function</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> onQuerySucceeded(sender, args) {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> alert(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">"The branding of your site was succesfully changed"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> window.location = window.location.href;<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">function</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> onQueryFailed(sender, args) {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> alert(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'Request failed. '</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> + args.get_message() +<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'\n'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> + args.get_stackTrace());<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span></div><div class="MsoNormal"><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">div</span><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">class</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">="ms-hide"></span><o:p></o:p></div>
</div>
<br />
Below the <<span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt;">webpartpages</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt;">:</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt;">webpartzone control, place the HTML code for the buttons:</span><br />
<br />
<div style="border:solid 1px silver;width:100%;overflow:scroll;white-space:pre">
<div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">div</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">class</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="ms-hide"></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">webpartpages</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">:</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">webpartzone</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">runat</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="server"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">title</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="loc:TitleBar"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">id</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="TitleBar"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">allowlayoutchange</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="false"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">allowpersonalization</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="false"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">style</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="</span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">display</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">: none;"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">/></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">div</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">br</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">br</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">a</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">href</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="JavaScript:branding();"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">id</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="brand-button"></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">Brand this site</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">a</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">br</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">/></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">a</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">href</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="JavaScript:unBranding();"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">id</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="unBrand-button"></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">Unbrand this site</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">a</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal"><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">table</span><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">class</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">="ms-core-tableNoSpace ms-webpartPage-root"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt; line-height: 115%;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">width</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">="100%"></span><o:p></o:p></div>
</div>
<br />
Finally, just before the end of the ContentPlaceHolder PlaceHolderMain section paste the code for disabling the button that is useless depending on the site is branded or not: <br />
<br />
<div style="border:solid 1px silver;width:100%;overflow:scroll;white-space:pre">
<div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">table</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"><</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">type</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">="text/javascript"></span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">var</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> logoUrl =$(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">".ms-siteicon-img"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">).attr(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'src'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">);<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> <o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">if</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> (logoUrl.indexOf(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'Contoso'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">) > -1) {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> document.getElementById(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'brand-button'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">).disabled = </span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">"disabled"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">;<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> document.getElementById(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'brand-button'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">).style.color = </span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">"silver"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">;<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> } </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">else</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> {<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> document.getElementById(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'unBrand-button'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">).disabled = </span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">"disabled"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">;<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> document.getElementById(</span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">'unBrand-button'</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">).style.color = </span><span style="background: white; color: #a31515; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">"silver"</span><span style="background: white; font-family: Consolas; font-size: 9.5pt;">;<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="margin-bottom: 0.0001pt;"><span style="background: white; font-family: Consolas; font-size: 9.5pt;"> </span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">script</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; mso-highlight: white;">></span></div><div class="MsoNormal"><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;"></</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">asp</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">:</span><span style="background: white; color: maroon; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">Content</span><span style="background: white; color: blue; font-family: Consolas; font-size: 9.5pt; line-height: 115%; mso-highlight: white;">></span><o:p></o:p></div>
</div>
<br />
<span style="color: #e9ab17; margin-left: 50px;">2.6 Testing the page</span><br />
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">After having copied the previous code at the right places within the Web Part page and well replaced the paths with the ones corresponding to the right locations of your environment you should obtain this scenario: <br />
When you land on the page for the first time the site is not branded and the "Unbrand this Site" link-button is disabled: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0c4qB7eKYu6z1SK_w_2BIalOHjIraX-Ly0wU38koQ21nyJnMSjhdJqqdC-b_SidhQnKCHMZ5jYNOLb2uFKOHJ2Un-lp6FviOj4K2YQljEbDvdz0JtATp7THdp201wSmyzE4WAglaNs1l/s1600/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+108+testing+the+page+-+before+branding.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0c4qB7eKYu6z1SK_w_2BIalOHjIraX-Ly0wU38koQ21nyJnMSjhdJqqdC-b_SidhQnKCHMZ5jYNOLb2uFKOHJ2Un-lp6FviOj4K2YQljEbDvdz0JtATp7THdp201wSmyzE4WAglaNs1l/s1200/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+108+testing+the+page+-+before+branding.jpg" class="screenshot-standard" ></a><br />
<br />
If you click on the "Brand" button, you are soon warned that the customizations were successfully performed: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5excjjtNhNeG44CzMYDTjyrdpOEWj5Q1KvZ-pksoVnkURbv1kDYQJTRchUxQQRREe8dmVg-bh92drSdBXMIO3HDLyKvrdZpFRHHvT-o7L5MZ-92Q_G7FUZVBcf7blQ7xpkk9lkgz2SA62/s1600/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+109+testing+the+page+-+Brand+buttom+clicked.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5excjjtNhNeG44CzMYDTjyrdpOEWj5Q1KvZ-pksoVnkURbv1kDYQJTRchUxQQRREe8dmVg-bh92drSdBXMIO3HDLyKvrdZpFRHHvT-o7L5MZ-92Q_G7FUZVBcf7blQ7xpkk9lkgz2SA62/s1200/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+109+testing+the+page+-+Brand+buttom+clicked.jpg" class="screenshot-standard" ></a><br />
<br />
Then, when you close the Javascript alert pop-up, you are relocated onto the same page, but with the new site branding! And you can also see that the "Brand" button has been disabled while the "UnBrand" button has been enabled.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc3L8aDPIc0ZBLvGZToj3V5IY_-F_H-kEBfLAehS-uzuiFrThQ_FwKDp3KQv5qKU3zjUQgbbbem0uVkVcKZMcg9l6fU7-icwuNLaokNQIwxmVYfYK_pJmbHrGHzNpW2byonCgOlFbrAafc/s1600/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+110+testing+the+page+-+Site+branded.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc3L8aDPIc0ZBLvGZToj3V5IY_-F_H-kEBfLAehS-uzuiFrThQ_FwKDp3KQv5qKU3zjUQgbbbem0uVkVcKZMcg9l6fU7-icwuNLaokNQIwxmVYfYK_pJmbHrGHzNpW2byonCgOlFbrAafc/s1200/Branding+SharePoint+Online+team+site+using+JavaScript+Code+Libray+110+testing+the+page+-+Site+branded.jpg" class="screenshot-standard" ></a><br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">3 - Aknowledgements</div><ul><li><a href="https://github.com/OfficeDev/PnP/tree/master/Samples/Branding.AlternateCSSAndSiteLogo">Vesa Juvonen and Jeremy Thake for the contribution on PnP</a><br />
<br />
</li>
<li><a href="https://gist.github.com/wictorwilen/d4e2435f336fcd5abff5">Wiktor Wilen contribution on Github</a><br />
<br />
</li>
<li><a href="https://blogs.office.com/2014/08/13/uservoice-driving-improvements-sharepoint-api/">UserVoice driving improvements to SharePoint API</a><br />
<br />
</li>
<li><a href="https://msdn.microsoft.com/en-us/library/office/jj244873.aspx">SP.Web object sp.js</a><br />
</ul></div></div>
</div>Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com0tag:blogger.com,1999:blog-4357140756496246910.post-75135002219039162632015-10-11T05:01:00.000+02:002019-09-05T19:41:36.027+02:00Branding a SharePoint Online Team Site<div class="h2-paragraph">
So, You have juste created your <a href="https://www.microsoft.com/en-us/evalcenter/evaluate-office-365-proplus">30
days SharePoint Online trial environment</a>, or have access to a licensed SharePoint Online environment and
want to brand a team site.<br />
<br />
From this...
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPA2lAuJaO1CkMkXPxs5yvHXX4IgBgTf69VT4ZWri12ArU0LoTHzNyVWmekyi61fnq9eITzyWQR2x20KQqk36PDvTf4h7qsjhmCtHFwVbxv26rEcL-BT2JWuBiVJn4arWP4nCLUM7YSmDU/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+01+-+Team+Site+Created.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPA2lAuJaO1CkMkXPxs5yvHXX4IgBgTf69VT4ZWri12ArU0LoTHzNyVWmekyi61fnq9eITzyWQR2x20KQqk36PDvTf4h7qsjhmCtHFwVbxv26rEcL-BT2JWuBiVJn4arWP4nCLUM7YSmDU/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+01+-+Team+Site+Created.jpg" /></a>
<br />
<br />
to this, for example...
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vcKMEttnkxAiaMSQyVmygYxDABqBAeUisgPo6XWwTychPYYJHEXwOq2rx9yCjDhsOjrUjVeSSzPT6I742ZvfCUOe-Cb85tqS8sGAlhiayG2KHynMrXVYEGnmAua3tNSzQjvhcnuXISTO/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+76-+the+home+page+is+working+despite+a+littlle+css+problem.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vcKMEttnkxAiaMSQyVmygYxDABqBAeUisgPo6XWwTychPYYJHEXwOq2rx9yCjDhsOjrUjVeSSzPT6I742ZvfCUOe-Cb85tqS8sGAlhiayG2KHynMrXVYEGnmAua3tNSzQjvhcnuXISTO/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+76-+the+home+page+is+working+despite+a+littlle+css+problem.jpg" /></a>
<br />
<br />
<br />
I am going to go through several ways to do it.First the "classical" one:
<br />
<ol>
<li>First, you can use a custom master page, custom CSS, without packaging all this and obtain a result in a very
quick time. (By the way, you can do it even faster by using the SharePoint Publishing Features but it is
not the case for this post. I chose for this post not using the Publishing Features in consideration of people
that bought a SharePoint Online environment where they are not available. I plan writing the same post while
using the Publishing Features) </li>
<li>You can, of course, package all your customizations done before within a .wsp also called a No-Code Sand-Boxed
Solution (NCSS) and redeploy all <br />
</li>
<li>And finally you can also use ShaePoint Add-Ins (formerly called Apps) for doing the same. <br />
</li>
</ol>
I will speak about these three ways of branding a SharePoint Online team site and will explain the pros and cons of
each. In this post, I will go through the two first approaches that are the old ones, providing a step by step
tutorial for carrying them out. I will dedicate a specific post for the last one (Add-Ins), but as I will explain
further on in this post, Add-ins, regarding this topic (SharePoint Online Branding) and until further notice from
Microsoft, are just an alternate choice with its own pros and cons.<br />
As a matter of fact, Microsoft recommends to use Add-Ins whenever you can, but recommends NCCSs for branding as the
easiest way to do it. (<a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">MSDN: SharePoint
Add-ins compared with SharePoint solutions</a>)<br />
<br />
I will finish the post by referencing <a href="http://mosshowto.blogspot.fr/2015/10/branding-sharepoint-online-javascript.html">another post of mine that
proposes <span style="background-color: yellow;">a fourth approach</span></a>. <span style="background-color: yellow;">This last approach uses together, WebDAV customisations, the SharePoint
JavaScript Object Model, while preserving the OOTB SharePoint templates used for the branding.</span>
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">
1 - Branding a SharePoint Online team site using webDAV</div>
<div a="" br="" can="" customizations="" example="" explorer="" file="" for="" in="" is="" library="" like="" mode="" open="" order="" page.="" page="" perform="" protocol="" sharepoint="" then="" this="" to="" use="" webdav="" within="" you="">
One of the most famous tool using webDAV protocol is SharePoint Designer, but you can open a SharePoint page in
webDAV mode using notepad, notepad ++ or Visual Studio.
style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">
1.1 Creating and customizing the Intranet Home page</div>
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">
We are now going to create the home page of our Intranet Site and perform the first cusotmizations. Navigate to the
Site Pages Library of your SharePoint Online Team Site. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNfnkuEyn8I4GscJJHEyvO1k9a7xDgvHInFSz0YeSO6vWubQDg2jIVewL4dh9Chn8UXQXnOYersDloUYthACEUDIlC68kFh-qLxAXk-3drJzUsnrBC-Jl8quAbVRhpC7mBm8BcaN3WurGu/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+02+-+Navigate+to+the+site+pages+library.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNfnkuEyn8I4GscJJHEyvO1k9a7xDgvHInFSz0YeSO6vWubQDg2jIVewL4dh9Chn8UXQXnOYersDloUYthACEUDIlC68kFh-qLxAXk-3drJzUsnrBC-Jl8quAbVRhpC7mBm8BcaN3WurGu/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+02+-+Navigate+to+the+site+pages+library.jpg" /></a><br />
<br />
Then, create a Web Part Page and name it home.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq6wq1rHRG9u21v2X1V4uDv4to56I4ZkgpTs4bnjlwgAGfugFCpsUxdwV82CQIPJ2X-OioEdf6_6uLjcIkXzFMSu21RRnhFruoCNNyfw1jml7TQQW8mpzfQs9CivFiq7WM4pFMKrwg3_aD/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+03+-+Creating+a+web+part+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq6wq1rHRG9u21v2X1V4uDv4to56I4ZkgpTs4bnjlwgAGfugFCpsUxdwV82CQIPJ2X-OioEdf6_6uLjcIkXzFMSu21RRnhFruoCNNyfw1jml7TQQW8mpzfQs9CivFiq7WM4pFMKrwg3_aD/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+03+-+Creating+a+web+part+page.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Ab8SlzWIa1-3qW3vVdLNI3VfnEpu5msmxfD3BtEbcx76c2X2RRwP-Ozqwxv3aDowoeeFuzprcExsMufJFZmcK6U06bOxYlrfxMk5lNkizsX14KF9rMc_vu9x0NP3Se7GJCbHKdKj4WGJ/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+04+-+Creating+a+web+part+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Ab8SlzWIa1-3qW3vVdLNI3VfnEpu5msmxfD3BtEbcx76c2X2RRwP-Ozqwxv3aDowoeeFuzprcExsMufJFZmcK6U06bOxYlrfxMk5lNkizsX14KF9rMc_vu9x0NP3Se7GJCbHKdKj4WGJ/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+04+-+Creating+a+web+part+page.jpg" /></a><br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_0ZTnn-FrTaMqDq1Z9GG6-mbfnNEDFun5afCquf6DFa1CeCDb8Z_qEfCATDCoDzQ_NGbsLrWgh-CrGrHbdPfxpPxjDdgbtCicf1EvrRh8C1Aw6A1t_KvnBsdudCqZT5zRS8Zs7tzj_-av/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+05+-+Creating+a+web+part+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_0ZTnn-FrTaMqDq1Z9GG6-mbfnNEDFun5afCquf6DFa1CeCDb8Z_qEfCATDCoDzQ_NGbsLrWgh-CrGrHbdPfxpPxjDdgbtCicf1EvrRh8C1Aw6A1t_KvnBsdudCqZT5zRS8Zs7tzj_-av/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+05+-+Creating+a+web+part+page.jpg" /></a><br />
<br />
Stop editing the page and navigate to the "Site Assets" library. Notice the look of the Home Web Part Page with the
default master page.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0ORwW-fBn0D7o7FVsp-iZufRPQbC58WvxuoFmpf4rTFbtPeX3Iffd1M5vTKYp-14HxILW_wktMMcMRQgwij0sf-j9sIiHgUwEwO0FHuznaVwCfAqHDH9DuW5THcvESo15lEUndpcBb5Iu/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+07+-+web+part+page+with+default+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0ORwW-fBn0D7o7FVsp-iZufRPQbC58WvxuoFmpf4rTFbtPeX3Iffd1M5vTKYp-14HxILW_wktMMcMRQgwij0sf-j9sIiHgUwEwO0FHuznaVwCfAqHDH9DuW5THcvESo15lEUndpcBb5Iu/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+07+-+web+part+page+with+default+master+page.jpg" /></a><br />
<br />
You will also notice that the Web Part Page was created in the "Site Assets" library.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq15-JnZn0GaryiT7lPRoIdgxEWW-H3_6g7-9RE9uyyLuLDrqKbiQJ5Zj578mpwMdHWAInPseM5T9z0UqiMg9leDBbcMceSbxTvz6z_nrBYWg_wPeQeHc_np1XSQ1H_f19tHl3FcbmHymv/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+06+-+web+part+page+created+in+the+Site+Assets+library.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq15-JnZn0GaryiT7lPRoIdgxEWW-H3_6g7-9RE9uyyLuLDrqKbiQJ5Zj578mpwMdHWAInPseM5T9z0UqiMg9leDBbcMceSbxTvz6z_nrBYWg_wPeQeHc_np1XSQ1H_f19tHl3FcbmHymv/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+06+-+web+part+page+created+in+the+Site+Assets+library.jpg" /></a><br />
<br />
Now is the time to open the page in webDAV mode to perform the first customization. Navigate through the page
contectual menu and locate "Open with SharePoint Designer". <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEB1hZPOiAg9Ws5PtyLI1K7E8w9xCYbvszdpVv0xq2LxKfece3QoxkzSn7Hb0aA52-hk6VsTFOkIT1i4oKCG6RKqEWaqVGQqWAl4Pr9_Dc6UHF7-pktDHwZ-768YytZP-MZX8LzcXT9Xtv/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+07+-+open+the+home+page+in+webDAV+mode.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEB1hZPOiAg9Ws5PtyLI1K7E8w9xCYbvszdpVv0xq2LxKfece3QoxkzSn7Hb0aA52-hk6VsTFOkIT1i4oKCG6RKqEWaqVGQqWAl4Pr9_Dc6UHF7-pktDHwZ-768YytZP-MZX8LzcXT9Xtv/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+07+-+open+the+home+page+in+webDAV+mode.jpg" /></a><br />
<br />
If you haven't SharePoint Designer installed on your computer, the source code of the page is displayed within the
notepad.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3imNXSItiQrDxzivVR1wmHJmGR269R4VKbj5WM13ITNbnj8tIy52jPQTnH0CDjA80-6CU3Uej1TUgmD_Jl6W4hHf3P_yVCJ5XNjZ4wbVDyikyYB3VaBr2YHY7lzD_FP3uCs4BdKE4onCK/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+09+-+code+of+the+web+part+page+showing+association+with+the+default+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3imNXSItiQrDxzivVR1wmHJmGR269R4VKbj5WM13ITNbnj8tIy52jPQTnH0CDjA80-6CU3Uej1TUgmD_Jl6W4hHf3P_yVCJ5XNjZ4wbVDyikyYB3VaBr2YHY7lzD_FP3uCs4BdKE4onCK/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+09+-+code+of+the+web+part+page+showing+association+with+the+default+master+page.jpg" /></a><br />
<br />
<br />
You can notice the line where the Home Web Part Page is associated with the default.maser master page.<br />
<br />
<span style="font-family: courrier-new;"><%@ Page language="C#" MasterPageFile="~masterurl/default.master"
</span><br />
<br />
We are going to change the association and make the Home page depend on the oslo.master master page. So change the
MasterPageFile attribute value with the relative path of the oslo.master master page. In my case, as my site is not
the root collection site, I had to use the "/sites/Intranet" segments in front of the path of the master pages
gallery:<br />
<br />
<span style="font-family: courrier-new;"><%@ Page language="C#"
MasterPageFile="/sites/intranet/_catalogs/masterpage/oslo.master" </span><br />
<br />
This is a view of the code of my Web Part Page after having performed the change. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi6pKqe02LVWJ6d3SqsrMD1q1jL-WUZxNXEH_DOmcT4n25_hXsPeogD-hVuVAldlMUWdCmOL1EvhPJP-0TaCNKNnm3nsrRevPC0NedsYVfDXcMX02P41xjNeFz3pRFj4anezvIAYQm3ID_/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+10+-+code+of+the+web+part+page+changed+with+a+new+association+with+the+oslo.master+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi6pKqe02LVWJ6d3SqsrMD1q1jL-WUZxNXEH_DOmcT4n25_hXsPeogD-hVuVAldlMUWdCmOL1EvhPJP-0TaCNKNnm3nsrRevPC0NedsYVfDXcMX02P41xjNeFz3pRFj4anezvIAYQm3ID_/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+10+-+code+of+the+web+part+page+changed+with+a+new+association+with+the+oslo.master+master+page.jpg" /></a><br />
<br />
<br />
Don't forget to save the changes, and when you refresh the page, you will notice that the layout of the page has
completely changed...<br />
This is due to the new association of the Home Web Part Page with the oslo.master master page.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilGKVuY92dQhdEjXdty9fIlVYy_QbVbMJ_Yqn4vdZFB69p9f9EqBsowPcR9kL93f4LYkcivAR0C8t339v7wTe6Dwx6BCkgGtFlSRdMpOACA7JjRYCRj5oLcaCjpivr7EERNyZvpzKPb_EI/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+11+-+The+layout+of+the+web+part+page+has+changed+with+the+new+association+with+the+oslo.master+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilGKVuY92dQhdEjXdty9fIlVYy_QbVbMJ_Yqn4vdZFB69p9f9EqBsowPcR9kL93f4LYkcivAR0C8t339v7wTe6Dwx6BCkgGtFlSRdMpOACA7JjRYCRj5oLcaCjpivr7EERNyZvpzKPb_EI/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+11+-+The+layout+of+the+web+part+page+has+changed+with+the+new+association+with+the+oslo.master+master+page.jpg" /></a><br />
<br /></div>
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">
1.2 Customizing the oslo.master master page in WebDAV mode</div>
<div style="color: grey; font-family: arial; font-size: 10pt; font-weight: normal; margin: 1px 0px; padding-bottom: 18px; padding-left: 18px; padding-right: 5px; padding-top: 5px; text-align: justify;">
Now, we are going to customize the oslo.master master page to give the home page a look and feel corresponding to
the famous Contoso company.<br />
Use Bing or Google images to find a logo of the Contoso company. Try to find one based on a .gif with transparency.
When it's done, create a folder called "images" in the site collection style library and download the Contoso logo
image in the folder.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlUEM8h8dbkXDejpshyphenhyphenPLxRGW2t6UVOvtwdVUQU-yRwFY0CUkFQdZaOQmnjvn4HF01pYC_QwsFMlk-WkUpz34Jzw2MlVjBgEFrjKasrmLt0SQ5_CDKPaiyqFRUCILsnk6CW_maE9tsCCM/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+12+-+downloading+the+Contoso+logo+to+the+images+folder+of+the+site+collection+style+library.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlUEM8h8dbkXDejpshyphenhyphenPLxRGW2t6UVOvtwdVUQU-yRwFY0CUkFQdZaOQmnjvn4HF01pYC_QwsFMlk-WkUpz34Jzw2MlVjBgEFrjKasrmLt0SQ5_CDKPaiyqFRUCILsnk6CW_maE9tsCCM/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+12+-+downloading+the+Contoso+logo+to+the+images+folder+of+the+site+collection+style+library.jpg" /></a><br />
<br />
<br />
Don't forget to check in the logo image, in order visitors of the site will be able to see it. (if the logo image is
checked out, only the administrator of the site will be able to see it).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTj6dm65hJN_RduQMmrz3ADsB5ciH8gWGVBufqezDXbP6f2wfY0HxZibAaqxMNL-PHOWVOO3dZE2TWWOulaayGxwR1ihvEQdwXnCZSv-435csMacNv6QM5KynvmhuTOUfrXSdGst6PRwUo/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+13+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTj6dm65hJN_RduQMmrz3ADsB5ciH8gWGVBufqezDXbP6f2wfY0HxZibAaqxMNL-PHOWVOO3dZE2TWWOulaayGxwR1ihvEQdwXnCZSv-435csMacNv6QM5KynvmhuTOUfrXSdGst6PRwUo/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+13+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" /></a><br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghrnIrs5xOZJQnFlZaGjE603KCDyPnROitVRM6EkUvSqm_KJY4ifO4KrL2IcUTGoBYMMPUtwwgoUOMUU1J55mT6bWeydSwLo-WY1yXptVivF2HGBSthMza9nG8LXnWIjq_5lPR-dhCnhU8/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+14+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghrnIrs5xOZJQnFlZaGjE603KCDyPnROitVRM6EkUvSqm_KJY4ifO4KrL2IcUTGoBYMMPUtwwgoUOMUU1J55mT6bWeydSwLo-WY1yXptVivF2HGBSthMza9nG8LXnWIjq_5lPR-dhCnhU8/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+14+-+checking+in+the+Contoso+logo+within+the+images+folder+of+the+site+collection+style+library.jpg" /></a><br />
<br />
Now, navigate to the master pages gallery and locate the oslo.master master page, and open it with SharePoint
Designer (or the notepad as we did before for the Home Web Part Page). <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNab9Ucn4Yjb7NCNvW2xDi4Ua7mXpF1GAT91ZbNcoIRTKt9U3lSnJ24Nqa_21vLMaTQd3PEsV7Xqjp052yIr-m-iIeBfKLYz8sqOZxOHdOpswY8umUUD-KYN3azvDiHtO-6zj1v9F4Un7R/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+15+-+opening+the+oslo.master+master+page+in+webDAV+mode.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNab9Ucn4Yjb7NCNvW2xDi4Ua7mXpF1GAT91ZbNcoIRTKt9U3lSnJ24Nqa_21vLMaTQd3PEsV7Xqjp052yIr-m-iIeBfKLYz8sqOZxOHdOpswY8umUUD-KYN3azvDiHtO-6zj1v9F4Un7R/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+15+-+opening+the+oslo.master+master+page+in+webDAV+mode.jpg" /></a><br />
<br />
While the source code of the oslo.master master page is edited within SharePoint Designer or the notepad, locate the
line displaying the SharePoint online default logo: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_810gnpspTnEk3EQPI2KGAme_AKnLPJ15lcCceND_aTG6bC78NEP20XSgcqXDlepb18YQOpaoa-EGveTr24aLqBlDaONxPKYelvqXRQpmVCIgQ69R0zhuC9TejSQWCTQK156L2PTHnF4x/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+16+-+locating+the+line+for+displaying+the+logo.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_810gnpspTnEk3EQPI2KGAme_AKnLPJ15lcCceND_aTG6bC78NEP20XSgcqXDlepb18YQOpaoa-EGveTr24aLqBlDaONxPKYelvqXRQpmVCIgQ69R0zhuC9TejSQWCTQK156L2PTHnF4x/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+16+-+locating+the+line+for+displaying+the+logo.jpg" /></a><br />
<br />
<br />
<span style="font-family: courrier-new;"><SharePoint:SiteLogoImage CssClass="ms-siteicon-img"
name="onetidHeadbnnr0" id="onetidHeadbnnr2" LogoImageUrl="/_layouts/15/images/siteIcon.png?rev=40"
runat="server"/></span><br />
<span style="font-family: courrier-new;"><br />
</span> Then change the line for displaying the Contoso logo you've just downloaded in the site collection style
library: <br />
<br />
<span style="font-family: courrier-new;"><SharePoint:SiteLogoImage CssClass="ms-siteicon-img"
name="onetidHeadbnnr0" id="onetidHeadbnnr2"
LogoImageUrl="/sites/intranet/Style%20Library/images/Contoso-Blue.png" runat="server"/>/></span><br />
<span style="font-family: courrier-new;"><br />
</span> The Home page of the Intranet is now displaying the logo of the Contoso company:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrGNnitsbs11OWEDu70TENeCv3YtUBvT1ecMR-a_qOm6OefZqQiCJkFv-TpxVavEi0fVYUvsQz7GCjmXhRNNdB54TO6lzKgQs_BTmi3HFeqpsPD__3W05P3DFUMtHqrI2DgaFF79qLL7gr/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+17+-+the+Intranet+home+page+is+displaying+the+Contoso+company+logo.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrGNnitsbs11OWEDu70TENeCv3YtUBvT1ecMR-a_qOm6OefZqQiCJkFv-TpxVavEi0fVYUvsQz7GCjmXhRNNdB54TO6lzKgQs_BTmi3HFeqpsPD__3W05P3DFUMtHqrI2DgaFF79qLL7gr/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+17+-+the+Intranet+home+page+is+displaying+the+Contoso+company+logo.jpg" /></a><br />
<br />
Now, we can add CSS to our customized oslo.master master page. So, locate the end tag of the <head> section
and paste the following styles: <br />
<br />
<span style="color: black; font-family: courrier-nex;"> <style><br />
#siteIcon{<br />
margin-top:0px;<br />
}<br />
#titleAreaBox{<br />
margin-top:0px;margin-left:20%; margin-right:20%;background-color:rgba(242, 242, 242, 1);<br />
}<br />
#titlerow{<br />
background-color:rgba(242, 242, 242, 1);<br />
}</span><br />
<span style="color: black; font-family: courrier-nex;">.noindex, ms-core-listMenu-horizontalBox{<br />
margin-top:30px; margin-left:-200px;<br />
}</span><br />
<span style="color: black; font-family: courrier-nex;">.ms-breadcrumb-box {<br />
padding-top: 5px;padding-bottom: 5px;height:30px;<br />
}<br />
#SearchBox{<br />
margin-left:200px;margin-right:-50px;<br />
}<br />
#suiteBarDelta{<br />
margin:0px;margin-top:-30px; <br />
}<br />
#DeltaPlaceHolderSearchArea{<br />
padding-top:45px;<br />
}<br />
.ms-srch-sb > input {<br />
width: 140px;<br />
}<br />
</style><br />
</head><br />
</span><br />
<br />
And you will obtain this new look for the home page:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrKa-YoimVob20DTX8K1Mjcn3uT-FHLnmmSAJfvHVleOjgwOek0lkFUtIn_qPRh4P7OUtQsRD81MyvO4xuPMWHf51840H6QDwl-Dn1hO_U3V612P3ynN8asPpMHky7b5Rmxro0SUJUjhXb/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+18+-+Intranet+home+page+after+having+added+styles+to+the+custom+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrKa-YoimVob20DTX8K1Mjcn3uT-FHLnmmSAJfvHVleOjgwOek0lkFUtIn_qPRh4P7OUtQsRD81MyvO4xuPMWHf51840H6QDwl-Dn1hO_U3V612P3ynN8asPpMHky7b5Rmxro0SUJUjhXb/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+18+-+Intranet+home+page+after+having+added+styles+to+the+custom+master+page.jpg" /></a><br />
<br />
Now, I am going to explain the pros and cons of customizing SharePoint Online that way:<br />
<br />
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">
1.3 Pros and Cons regarding the customization of SharePoint Online using WebDAV mode (SharePoint Designer or
other editors)</div>
When you make changes on a SharePoint page (Web Part Page, Wiki Page, Master Page) using
webDAV protocol the link between the page and the OOTB template which the page is based on is temporary broken. The
page which you have made changes on, goes in the SharePoint content databases. <br />
These kinds of pages where you have performed changes using webDAV and stored in the SharePoint databases were
called until 2010 "unghosted" pages and was renamed since 2010 in "customized" pages. <br />
Notice that you obtain exactly the same result when you download a page directly in a SharePoint library (Site
Pages, Site Assets, Master pages gallery)<br />
<br />
On the opposite a page based on a template remaining on the SharePoint Farm servers was called until 2010 a
"ghosted" page, and since 2010 an "uncustomized" page. There are two kinds of uncustomized pages: the OOTB
SharePoint pages of course, but also the pages deployed to a SharePoint Farm or Site Collection by using a
SharePoint solution (.wsp) and activated in a SharePoint library using a SharePoint Feature. <br />
<br />
So, the cons of branding a SharePoint site (on prem or Online) using webDAV protocol are roughly the same than using
"customized" pages: <br />
<ul>
<li>Your customizations are not stored in a Source Code Control System, so your customizations are hardly
maintainable.<br />
</li>
<li>There is a feature in SharePoint Called "Reset to site definition" that fixes the broken link with the
SharePoint template remained on the servers. This feature restore the "customized" or "unghosted" page to
its original "uncustomized" or "ghosted" state. But using "Reset to site definition" and restoring the page
in its original state will also lead to the loss of all your customization! Very unsafe.<br />
</li>
<li>As your customized pages are not based on a OOTB SharePoint template anymore, if Microsoft makes any update
on the SharePoint templates, these updates won't be taken into account by your customized page. You will
lost new features of the product and maybe even current ones depending on the Microsoft updates.<br />
</li>
<li>Last, because the customized pages are stored in the SharePoint content databases, some says that using
these kinds of pages leads to a loss of performances. I am not sure if it is true or not. <br />
</li>
</ul>
<br />
Facing all these cons regarding the use of the webDAV protocol to give a SharePoint Online site a personal look and
feel you are certainly thinking: "Why doing this that way?" So here are the pros, and there are also many: <br />
<ul>
<li>It is very quick and cheap. You know the main IT key success factor : Time to market! Customizing SharePoint
that way allows you to provide your management or your customer with a very quick response to their
requirements. It is cheap not only because it's quick done, but also because there is no need that people
doing it to be "expensive SharePoint experts". A good web designer, doing it that way, will acquire the
necessary knowledge to brand any SharePoint Online site within a few weeks.<br />
</li>
<li>If you are working within an well structured organisation, an organisation good at formalizing processes,
all this can be done safely: keeping an history of all the customizations, keeping a copy of all the
modified files in a Source Code Control System,etc. I recently helped a big French bank in setting up all
these processes and performing a part of them automatically.<br />
</li>
<li>Last but not least, customizing a site using webDAV can lead to a "cleaner" way of delivering the solution,
without modifying or losing the work already done. It could be just a first round of a project in order to
provide your stakeholders with the rough website layout. This can be properly repackaged when the
stakeholders are (finally) ok for the look and feel of the site. I advice any SharePoint developer to start
working on a branding project using webDAV, then, package the customizations when they obtain the go from
their management or client.<br />
Packaging operations and deployments for SharePoint are expensive in matter of efforts and time. Saving this
precious time at the beginning of the project will lead to a more cost effective way of customizing
SharePoint.<br />
</li>
</ul>
So let me show you now, how to repackage and redeploy ("properly") all the previous customizations: <br />
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">
2 - Branding a SharePoint Online team site using Visual Studio and No-Code Sand-boxed Solutions (NCSS)</div>
<div style="color: #e9ab17; font-weight: normal; margin: 1px 0px; padding-bottom: 10px; padding-left: 26px; padding-top: 10px;">
2.1 Establishing the To Do list</div>
So, let's summarize the customizations performed in webDAV mode : <br />
<ul>
<li>we have created a custom Web Part Page and customized it by referencing an alternate Master Page. <br />
</li>
<li>we have customized the oslo.master Master Page by adding custom CSS within a <style> tag in order to
use it as an alternate Master Page. <br />
</li>
<li>we have downloaded the logo image within a new "images" folder of the "styles" library <br />
</li>
</ul>
<br />
What have we to do in order to be more compliant with the usual practices? We have to : <br />
<ul>
<li>Package the custom Web Part Page and deploy it using a No-Code Sand-boxed Solution<br />
</li>
<li>Package the custom Master Page based on the native oslo.master Master Page in the same NCSS package and by
the way, after having deployed the package, reset to site definition the customized oslo.master Master Page
in order it returns to its original "uncustomized" state.<br />
</li>
<li>do nothing for the image logo, because it is ok to download directly the logo image within a new "images"
folder within the "styles" library, so let it done as it's already done.<br />
</li>
<li>put the CSS embedded in the custom Master Page in a .css file and download it in the Styles library (same
treatment than the logo image)<br />
</li>
</ul>
So, let's do it, and after of course, I will explain the pros and the cons of customizing a SharePoint Online
site using No-Code Sand-boxed Solutions or NCSS. <br />
What do we need for doing this? <br />
At least, a computer with Visual Studio 2013 installed on it. The best is to have a virtual machine where SharePoint
2013 and Visual Studio are installed. I have a <a href="http://mosshowto.blogspot.fr/2012/10/installation-sharepoint-2013-windows.html">post explaining how to
install this kind of environment</a> (plan at least one day of work for mounting such an environment)<br />
Of course, you can build your NCSS package using Visual Studio and publish it directly from Visual Studio within
SharePoint Online, but in case of errors it would be difficult to debug. <br />
<br />
<br />
<span style="color: #e9ab17;">2.2 Checking the environment and creating the project</span><br />
<br />
First of all, be sure to have a SharePoint site on your on premise environment with the same acces URL than in that
your SharePoint Online. If not create it.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghElYsMDUtDIL4k2VXL5BO9MLN9ThxGUyIcmseJh01-ScdJ4OcTwt2Al76xCV-JsWT-G3yQNCGRniqlzTjEcLZuwG4yKq9KevsLfGUs5CCM1nlX0F22J2kDOidx-Hk3Q7fjFbJhQgRiovt/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+18+-+01+be+sure+to+have+a+on+prem+site+with+the+same+path+as+Online+site.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghElYsMDUtDIL4k2VXL5BO9MLN9ThxGUyIcmseJh01-ScdJ4OcTwt2Al76xCV-JsWT-G3yQNCGRniqlzTjEcLZuwG4yKq9KevsLfGUs5CCM1nlX0F22J2kDOidx-Hk3Q7fjFbJhQgRiovt/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+18+-+01+be+sure+to+have+a+on+prem+site+with+the+same+path+as+Online+site.jpg" /></a><br />
<br />
Then, continue by opening Visual Studio and creating the project. A SharePoint 2013 Empty Project will be fine.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHsPVfL8O2LCn0kFy9WZ3Jsjm93uJGiVd8nKwxB4u-goCdMyipSx9pT5ZdHN7ANwRmyvVnoV3RFFeZ8ZgixWiTkby_rUsuExxINrfEuEau6OHNu-bPMyaEEA-eu-KZrq2ThdFJ7W1XPmBw/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+19+-+Creating+the+Visula+Studio+Project.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHsPVfL8O2LCn0kFy9WZ3Jsjm93uJGiVd8nKwxB4u-goCdMyipSx9pT5ZdHN7ANwRmyvVnoV3RFFeZ8ZgixWiTkby_rUsuExxINrfEuEau6OHNu-bPMyaEEA-eu-KZrq2ThdFJ7W1XPmBw/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+19+-+Creating+the+Visula+Studio+Project.jpg" /></a><br />
<br />
Type the URL of your on premise SharePoint Site as the site used for debugging, and choose to deploy your project
package as a Sandboxed Solution since the final aim is to deploy this package within SharePoint Online. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ3lPFNBnXYZEbt_QiZI7wvKZPpRZclYUkMcQmOCXGn_OOGmgyGk0WZ9kQsuxjbfF3CsoBn4ZLet2MyypSf660RE05G5lbAA8HnDpSEHi-4ysPcfOFFPESvCNaW7CXkFhV23Sd8PALtDkE/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+19+-+Setting+the+testing+site.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ3lPFNBnXYZEbt_QiZI7wvKZPpRZclYUkMcQmOCXGn_OOGmgyGk0WZ9kQsuxjbfF3CsoBn4ZLet2MyypSf660RE05G5lbAA8HnDpSEHi-4ysPcfOFFPESvCNaW7CXkFhV23Sd8PALtDkE/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+19+-+Setting+the+testing+site.jpg" /></a><br />
<br />
The next screenshot shows Visual Studio after the project is created. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMCMkIO5h-HXNJXRTWMRLONh3tvIQJXtgp-5wh2HtBoABuRD6VQFxutJCGcX-G0GEs1pprkRSaFl8YUDh1iTx7Lp_ml1YAGJsXibMkZRP-avpYVniJ6hM98aDu8rayKrIAOclIGLeb36H9/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+20+-+IntranetBranding+Project+created+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMCMkIO5h-HXNJXRTWMRLONh3tvIQJXtgp-5wh2HtBoABuRD6VQFxutJCGcX-G0GEs1pprkRSaFl8YUDh1iTx7Lp_ml1YAGJsXibMkZRP-avpYVniJ6hM98aDu8rayKrIAOclIGLeb36H9/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+20+-+IntranetBranding+Project+created+.jpg" /></a><br />
<br />
<span style="color: #e9ab17;">2.3 Creating the Module Feature</span><br />
<br />
Right click the Feature Folder and click Add Feature. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQvPWnhX8JAoq7nZWA9WqsJTs3MNLDNI5-NAW_DZtGKSoEcQ7QijxzfaTsk0HduxO0_lv25w434DNcRjqAyy2KaHUd4Szd7ALabEadtjZrmEoX1mzFU3wNL0M4wUCPObcSI7Vy26Q7YofD/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+21+-+IntranetBranding+Project+creating+a+feature+.jpg" imageanchor="1"><img border="0" class="screenshot-medium" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQvPWnhX8JAoq7nZWA9WqsJTs3MNLDNI5-NAW_DZtGKSoEcQ7QijxzfaTsk0HduxO0_lv25w434DNcRjqAyy2KaHUd4Szd7ALabEadtjZrmEoX1mzFU3wNL0M4wUCPObcSI7Vy26Q7YofD/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+21+-+IntranetBranding+Project+creating+a+feature+.jpg" /></a><br />
<br />
After the feature is created, rename all that you can in order your project to be understandable for anybody who
would have to open it or maintain it. The title will be displayed within the SharePoint UI, so find an really
explicit name. I should have rather called my Feature "Contoso - Add Intranet Pages".<br />
Notice that I gave a "Site" scope to my feature since it has to register a Master Page, and that the Master Page
gallery is at the Site Collection level.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGMOKUl-X4U4vJJJBBun-GaLSpo3SgfKGAMXlubQDBy7cD58DG8zIHky_wLGMkhd5_DBGvPYppSby6-LBkp_6glDU873t0i9Xz_aQn03ul8K7edZ_2tMUC4Enyg_PS1nIcahyphenhyphenfvcS5aENc/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+22+-+IntranetBranding+Project+creating+a+feature+-+feature+settings.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGMOKUl-X4U4vJJJBBun-GaLSpo3SgfKGAMXlubQDBy7cD58DG8zIHky_wLGMkhd5_DBGvPYppSby6-LBkp_6glDU873t0i9Xz_aQn03ul8K7edZ_2tMUC4Enyg_PS1nIcahyphenhyphenfvcS5aENc/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+22+-+IntranetBranding+Project+creating+a+feature+-+feature+settings.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga1ExU7DQloZqWPWRpbMSyYeTWEHjt5qllFDsPjVqPYpMx5DQLvBwbNeMvAdtBg2gT0vkPfwM08L8Fyfe8qMMNlXZLk6ZT1EnUOkduEzn-4UqOSn1hjUfb2bYCtKDK_SAOZyyHsX25MkEw/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+23+-+IntranetBranding+Project+creating+a+feature+-+feature+settings+02.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga1ExU7DQloZqWPWRpbMSyYeTWEHjt5qllFDsPjVqPYpMx5DQLvBwbNeMvAdtBg2gT0vkPfwM08L8Fyfe8qMMNlXZLk6ZT1EnUOkduEzn-4UqOSn1hjUfb2bYCtKDK_SAOZyyHsX25MkEw/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+23+-+IntranetBranding+Project+creating+a+feature+-+feature+settings+02.jpg" /></a><br />
<br />
Then, right click the project and navigate in order to Add A New Item.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyY45WxmrETF5lS8if2yhci6iAERyZuLbkewz4a4vWkp0wsRnfuiG8ZLS-mBnlG0o1AlxoJcCnCAyodwv2PGdUiv7-xMgxQ_CNslI7U2CIRzhvGvyw_yyHAEeO7M1Z0s_N18moZ9WcCo30/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+24+-+IntranetBranding+Project+creating+a+feature+-+Adding+Module+01.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyY45WxmrETF5lS8if2yhci6iAERyZuLbkewz4a4vWkp0wsRnfuiG8ZLS-mBnlG0o1AlxoJcCnCAyodwv2PGdUiv7-xMgxQ_CNslI7U2CIRzhvGvyw_yyHAEeO7M1Z0s_N18moZ9WcCo30/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+24+-+IntranetBranding+Project+creating+a+feature+-+Adding+Module+01.jpg" /></a><br />
<br />
As said before, name the module so as anybody can understand its utility<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOZw2DJ2ffkX6_MvCAQzLiNmKDrY3bxrJQrzgmZLJ2FLwJ5lwx2dDl5_hsq04pnx_8_11kZvjg3kty-jWajbS0-Vle-qYor257k84bx259pPtpDoOcjIV2N_-WAOa1Elmik4E8POGTVdBp/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+25+-+IntranetBranding+Project+creating+a+feature+-+Adding+module+02.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOZw2DJ2ffkX6_MvCAQzLiNmKDrY3bxrJQrzgmZLJ2FLwJ5lwx2dDl5_hsq04pnx_8_11kZvjg3kty-jWajbS0-Vle-qYor257k84bx259pPtpDoOcjIV2N_-WAOa1Elmik4E8POGTVdBp/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+25+-+IntranetBranding+Project+creating+a+feature+-+Adding+module+02.jpg" /></a><br />
<br />
The next screenshot shows Visual Studio after the module is created. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXFYD0pFKSXRA7Cni6UJHA6m9fvi19JUdrKdk7WLozBBwCrS7xYQ3CYpP6I47Neu3GTl-a9jW1l4TAcibXzkdPlJrQ1gIBemDzmelBBcIAcD1sB9alCyCtgHx9jjPGJrn9KOoEwuk3OUS2/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+26+-+IntranetBranding+Project+creating+a+feature+-+Module+Added+01.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXFYD0pFKSXRA7Cni6UJHA6m9fvi19JUdrKdk7WLozBBwCrS7xYQ3CYpP6I47Neu3GTl-a9jW1l4TAcibXzkdPlJrQ1gIBemDzmelBBcIAcD1sB9alCyCtgHx9jjPGJrn9KOoEwuk3OUS2/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+26+-+IntranetBranding+Project+creating+a+feature+-+Module+Added+01.jpg" /></a><br />
<br />
You can also notice that the module has been automatically added to the previously created Feature. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm4xLC8yv81SVXgML7dxnhxp2LLGs5_9Cfh48cuc1qkiNfPGcw92InZJEZCGlbTi3p4DXHG8BtAjqoELmYxVRjcdFAfGEcnrPlo8oSl2bbjWdk71O07TJ4oXt0g50e6ufm0qAerUTlWdfc/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+27+-+IntranetBranding+Project+creating+a+feature+-+Module+Added+02.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm4xLC8yv81SVXgML7dxnhxp2LLGs5_9Cfh48cuc1qkiNfPGcw92InZJEZCGlbTi3p4DXHG8BtAjqoELmYxVRjcdFAfGEcnrPlo8oSl2bbjWdk71O07TJ4oXt0g50e6ufm0qAerUTlWdfc/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+27+-+IntranetBranding+Project+creating+a+feature+-+Module+Added+02.jpg" /></a><br />
<br />
<span style="color: #e9ab17;">2.4 Adding a Master Page to the Module Feature</span><br />
<br />
Right click the sample.txt file and rename it "Contoso.Intranet.master", then click "Yes" to the message that warns
you that you are changing the extension. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5UQTxdEf8lNGHd2ANMYVNti-pII2HCIRDi5H3jiP1dGDjtWzR9UBU1wrDCU6rgZ0E19mJaFQD0sGvUqVEY3CcY_zdH00Ku6QojVK4Rn909DJ7o5GjhXVvqxKkvAUZddJz1B1wrg39pRLI/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+28+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5UQTxdEf8lNGHd2ANMYVNti-pII2HCIRDi5H3jiP1dGDjtWzR9UBU1wrDCU6rgZ0E19mJaFQD0sGvUqVEY3CcY_zdH00Ku6QojVK4Rn909DJ7o5GjhXVvqxKkvAUZddJz1B1wrg39pRLI/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+28+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNopCz3hTltAl6cMac7BjwhyZUf2k60ypIx9Mc0r_8S4TFh2_5OKGRmHzX-nlkRX9K7GkbmjGbVEOD6msBjgMrgZF_vEs6pouVAQvuxaJf3gsfj_KxC7yOo_qwhzp_rCAv8WnjPVowlk5l/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+29+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file+02.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNopCz3hTltAl6cMac7BjwhyZUf2k60ypIx9Mc0r_8S4TFh2_5OKGRmHzX-nlkRX9K7GkbmjGbVEOD6msBjgMrgZF_vEs6pouVAQvuxaJf3gsfj_KxC7yOo_qwhzp_rCAv8WnjPVowlk5l/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+29+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file+02.jpg" /></a><br />
<br />
After having renamed the file, you will notice that Visual Studio has changed the icon into an icon of a Master Page
file, and that the file element.xml of the module has been updated. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVjrYnFhzGAMlYfPzB9mup63a-nj3zrololECNdhWonX8VzKTmuCl2kZ42RlBAcrHGGlUZ0XHvcVzcw6B0MYXc6OMkwEI87YgQwwKzulifgLETWD2_B3ui6Ov_KTpFisnxe1iY50pf65R7/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+29+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file+03.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVjrYnFhzGAMlYfPzB9mup63a-nj3zrololECNdhWonX8VzKTmuCl2kZ42RlBAcrHGGlUZ0XHvcVzcw6B0MYXc6OMkwEI87YgQwwKzulifgLETWD2_B3ui6Ov_KTpFisnxe1iY50pf65R7/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+29+-+IntranetBranding+Project+creating+a+feature+-+renaming+sample+file+03.jpg" /></a><br />
<br />
Click on the Contoso.Intranet.master within Visual Studio to edit the source code of the page. For now, you see only
the text of the previous txt file. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuZs7pkshaSF1VooT6mrXPXJnoSRu_VNT70U9xiAc75PEn_5Ve-9wp2QgPS9sHuy17imAOeM4S-qWZWYsalDV0x-r_IsS_kWf8Oyc9OQJ16bKv-i2dzPNdOhInkpACV7j8GJp6xE_XWmER/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+30+-+IntranetBranding+Project+creating+a+feature+-+opening+Contoso.Intranet.master.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuZs7pkshaSF1VooT6mrXPXJnoSRu_VNT70U9xiAc75PEn_5Ve-9wp2QgPS9sHuy17imAOeM4S-qWZWYsalDV0x-r_IsS_kWf8Oyc9OQJ16bKv-i2dzPNdOhInkpACV7j8GJp6xE_XWmER/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+30+-+IntranetBranding+Project+creating+a+feature+-+opening+Contoso.Intranet.master.jpg" /></a><br />
<br />
Now, we are going to copy the source code of the oslo.master Master Page that we have previously customized in
webDav mode. So go to your SharePoint Online environment and open the oslo.master using webDav protocol, and copy
the source code. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpQozfDQZsiBcIzm4a3rK-vqe34rR703Uki9dtB8VsB3RHyPlHEai5zdwtH0T-1woTnWsavJzyeZiABJHj1diwbmnPh9rJnj5rH_AsB65KPJvpPULMLOhybt4Tkw3CL9k_qUTg0FMUkSD/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+31+-+copying+the+source+code+of+the+oslo.master+master+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpQozfDQZsiBcIzm4a3rK-vqe34rR703Uki9dtB8VsB3RHyPlHEai5zdwtH0T-1woTnWsavJzyeZiABJHj1diwbmnPh9rJnj5rH_AsB65KPJvpPULMLOhybt4Tkw3CL9k_qUTg0FMUkSD/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+31+-+copying+the+source+code+of+the+oslo.master+master+page.jpg" /></a><br />
<br />
Then, paste the code in the Contoso.Intranet.master file edited within your Visual Studio. You can see now the code
you have modified in webDav mode colorized by Visual Studio. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-U1BW2N1iflOnrbDqh_0M8uVWEmdslx6A_ax_8UXIuN3c1uTxWbf7BA78m-R2VtLrr3oa_eGz_ueHtiuAOq9feHp8toTR4fPMuSOo0c5DvuwWi-QFCjP0cuz_sYPVFJkwFmQlT-QTBCP/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+32+-+source+code+of+the+Contoso.Intranet.master+copied.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-U1BW2N1iflOnrbDqh_0M8uVWEmdslx6A_ax_8UXIuN3c1uTxWbf7BA78m-R2VtLrr3oa_eGz_ueHtiuAOq9feHp8toTR4fPMuSOo0c5DvuwWi-QFCjP0cuz_sYPVFJkwFmQlT-QTBCP/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+32+-+source+code+of+the+Contoso.Intranet.master+copied.jpg" /></a><br />
<br />
<span style="color: #e9ab17;">2.5 Moving the css from the Master Page to a dedicated .css file</span><br />
<br />
Now, as said before, we are going to put the CSS currently present in the Master Page in a dedicated .css file, so
using the Module contextual menu: "Add --> New Item", add a new css file to your Module. Take care as usual
giving the .css file an explicit name. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJfF_TN1fTMTHUGFYyASMHXevzcv5nyfaXar2mGlvafYftpCd1DE6zXpTWqwBRToKfIMG2vi-zc7u_CJlG_q5sFghSbXLuxrnUN9_tr5tsJJtbQBcMQuUCSEoSy8Ae-qaPyiDZgd2HYLLS/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+32+-+creating+the+Contoso.Intranet.css+file.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJfF_TN1fTMTHUGFYyASMHXevzcv5nyfaXar2mGlvafYftpCd1DE6zXpTWqwBRToKfIMG2vi-zc7u_CJlG_q5sFghSbXLuxrnUN9_tr5tsJJtbQBcMQuUCSEoSy8Ae-qaPyiDZgd2HYLLS/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+32+-+creating+the+Contoso.Intranet.css+file.jpg" /></a><br />
<br />
So, locate the custom styles added before in WebDAV mode in the oslo.master Master Page, and cut them...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-bKjt0_gKAJzzftKrk1kSMLLoUoMsfQEoipHr9THd77TIuPZKCr4Qvm6g3ZRffToBUDMemFfHSeGxciXE9msfI0cT-ZCzKRmq-rBMv1C0krx0EP-4rF3M1USrwFG0fpNmIWqzwcVBEea/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+34+-+cutting+the+custom+styles.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-bKjt0_gKAJzzftKrk1kSMLLoUoMsfQEoipHr9THd77TIuPZKCr4Qvm6g3ZRffToBUDMemFfHSeGxciXE9msfI0cT-ZCzKRmq-rBMv1C0krx0EP-4rF3M1USrwFG0fpNmIWqzwcVBEea/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+34+-+cutting+the+custom+styles.jpg" /></a><br />
<br />
then, paste them in the new .css file that you have just created... <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnaQvVNiOfrqwS4RQJ1fsRS3bdzgr33YTu_1Vsh1r9w9ugjc3NTZ6hHpm9PWvwpNMUp17t19NhXeITJWvj3ZsebFX0Io85Whah00PAZ2GGxwPlMgxbwwqFcIDBAfDy3ng8gRtFM96AxNy8/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+35+-+pasting+the+custom+styles+in+the+Contoso.Intranet.css+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnaQvVNiOfrqwS4RQJ1fsRS3bdzgr33YTu_1Vsh1r9w9ugjc3NTZ6hHpm9PWvwpNMUp17t19NhXeITJWvj3ZsebFX0Io85Whah00PAZ2GGxwPlMgxbwwqFcIDBAfDy3ng8gRtFM96AxNy8/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+35+-+pasting+the+custom+styles+in+the+Contoso.Intranet.css+.jpg" /></a><br />
<br />
finally, delete the empty <style> section in the Master Page<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaEtpW8ZRqBJ1XFAt9jcFKeMsqGcy2XKB-EgbYgGACL0M5oxHCDYXsZLKstxN3bYrwurUHi8Wwu-FXiQ5pVsj7tnXXDig3R2mavl__M-J82BzTfWMggy7eEWeZZOmdXGOYGsP3AcDLpPaQ/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+36+-+deleting+the+style+section+in+the+Contoso.Itranet.master+master+page+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaEtpW8ZRqBJ1XFAt9jcFKeMsqGcy2XKB-EgbYgGACL0M5oxHCDYXsZLKstxN3bYrwurUHi8Wwu-FXiQ5pVsj7tnXXDig3R2mavl__M-J82BzTfWMggy7eEWeZZOmdXGOYGsP3AcDLpPaQ/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+36+-+deleting+the+style+section+in+the+Contoso.Itranet.master+master+page+.jpg" /></a><br />
<br />
<br />
<span style="color: #e9ab17;">2.6 Registering the .css file within the Master Page</span><br />
<br />
But now, we have to register the .css file within the new master page. To do it, the best is to use the SharePoint
control <SharePoint:CssRegistration. So, locate the current <SharePoint:CssRegistration control and duplicate
it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0mMSfEWhrAxlF4fcuzWYKUSZ38KLuSpgIgNRfUyF5rVsJjq2bMjLdHY1dplSKl-56EDkdc4XxYjDxZ-8hAOYZ-yIrKVmFpOHWBujIxKEGbASkSM6Qrvv9uQrgitIQFRbt0u96Z-hIUYfj/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+37+-+new+css+registration+within+the+Contoso.Itranet.master+master+page+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0mMSfEWhrAxlF4fcuzWYKUSZ38KLuSpgIgNRfUyF5rVsJjq2bMjLdHY1dplSKl-56EDkdc4XxYjDxZ-8hAOYZ-yIrKVmFpOHWBujIxKEGbASkSM6Qrvv9uQrgitIQFRbt0u96Z-hIUYfj/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+37+-+new+css+registration+within+the+Contoso.Itranet.master+master+page+.jpg" /></a><br />
<br />
Notice that, if you click on the control within Visual Studio, you have the control properties displayed within the
properties windows, and you can see a property called "After". This property allows you to give an order regarding
the way the <Link html tag are rendered. This is important beacause we want that our custom css to be rendered
after the SharePoint native ones because we want our custom css to overwrite the SharePoint native ones. <br />
That is why I gave to the control ("Name" property) the URL I planned for the custom css (not deployed yet) and I
specified "oslo.css" for the value of the property "After".<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhklTXN0bwFlMLY8gADP5LeEClP15Ba5J2QQPnYcq6RrZM-Zjxx6CjmZB7eVW-9fLZjC5uOlbbx-ALFb-913aVgqaFZS0zEf2lM610lxuLzmcU3NT6zbdhGej_AwmvG5-djxkIIRAzF4bQ/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+38+-+new+css+registration+within+the+Contoso.Itranet.master+master+page+done+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhklTXN0bwFlMLY8gADP5LeEClP15Ba5J2QQPnYcq6RrZM-Zjxx6CjmZB7eVW-9fLZjC5uOlbbx-ALFb-913aVgqaFZS0zEf2lM610lxuLzmcU3NT6zbdhGej_AwmvG5-djxkIIRAzF4bQ/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+38+-+new+css+registration+within+the+Contoso.Itranet.master+master+page+done+.jpg" /></a><br />
<br />
<span style="color: #e9ab17;">2.7 Creating the new Home page for the Intranet site</span><br />
<br />
Now, we are going to create the new home page for the Intranet site, so use again the conextual menu of the Module
element for adding a New Item. As there is no .aspx file available in the Visual Studio templates, choose an HTML
page and add it to the Feature Module. The trick is to change the extention in .aspx in the modal window...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyzXser97BoRkUijQYYv1ovZ41iECUz1qrZy5GVAHcNvPGdXdgzLOY-_s8UsWXOnv_qMBC8nXzHP27JBYwzosOtZ9nTx2hvH94ndZ4aG-0Llck7rPuArZrQ9Tm4jikogewAyY2AIBA956q/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+39+-+new+Contoso.Intranet.home.aspx+.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyzXser97BoRkUijQYYv1ovZ41iECUz1qrZy5GVAHcNvPGdXdgzLOY-_s8UsWXOnv_qMBC8nXzHP27JBYwzosOtZ9nTx2hvH94ndZ4aG-0Llck7rPuArZrQ9Tm4jikogewAyY2AIBA956q/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+39+-+new+Contoso.Intranet.home.aspx+.jpg" /></a><br />
<br />
...in order to obtain a .aspx file recognized as well by Visual Studio: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB_vZ5DGbS8yV33XNT6UKfB-obCECqoNB3WSgpjmGoII9hac7LgeXkLgrtQKqJJL3_QPHQRtCBspEQxvFbx1YwX3YBh5p4MCJb_TERh2P03JEam5E31X6iKKmkEHQ6HKn8vrKKaNHiJ_uQ/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+40+-+new+Contoso.Intranet.home.aspx+added.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB_vZ5DGbS8yV33XNT6UKfB-obCECqoNB3WSgpjmGoII9hac7LgeXkLgrtQKqJJL3_QPHQRtCBspEQxvFbx1YwX3YBh5p4MCJb_TERh2P03JEam5E31X6iKKmkEHQ6HKn8vrKKaNHiJ_uQ/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+40+-+new+Contoso.Intranet.home.aspx+added.jpg" /></a><br />
<br />
As we did before for the master page, we are going to paste the source code of the previously modified Home Page
(Home.aspx) within SharePoint Online using webDAV protocol. <br />
So, open the Home.aspx in webDAV mode and copy the source code. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZxtquL_m97x4ThSgAUBoekZYWay8G1rH3DtZ-Eq8BV1H3oultq-3ruast6Jr2xV29lo72oo3pz23_3qvNuoexH3G50fFdjcrN1iJQn6iTlvGlwNtz1XVAmZ-esDdxizYNAwRn6UfLjJb2/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+41+-+copying+the+source+code+of+the+home.aspx+web+part+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZxtquL_m97x4ThSgAUBoekZYWay8G1rH3DtZ-Eq8BV1H3oultq-3ruast6Jr2xV29lo72oo3pz23_3qvNuoexH3G50fFdjcrN1iJQn6iTlvGlwNtz1XVAmZ-esDdxizYNAwRn6UfLjJb2/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+41+-+copying+the+source+code+of+the+home.aspx+web+part+page.jpg" /></a><br />
<br />
and paste this customized code within the freshly created Contoso.Intranet.Home.aspx<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZi6cvvr8AL0ocX70TLb0k-7BgWVyVqYXxne3-oJ_KU0DkmlA2G2S489ZeEgr5L-xmY3XI4UjiwWsRuUUMOp5F3uxMz7sHv_utTi13QZ2xxTu-0uu5FTHyI6FdccjN2rUOBc0p7oVxLJn6/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+42+-+source+code+copied+in+the+new+Contoso.Intranet.home.aspx.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZi6cvvr8AL0ocX70TLb0k-7BgWVyVqYXxne3-oJ_KU0DkmlA2G2S489ZeEgr5L-xmY3XI4UjiwWsRuUUMOp5F3uxMz7sHv_utTi13QZ2xxTu-0uu5FTHyI6FdccjN2rUOBc0p7oVxLJn6/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+42+-+source+code+copied+in+the+new+Contoso.Intranet.home.aspx.jpg" /></a><br />
<br />
But now, we have to change the reference to the master page since we want to use the custom Master Page we have just
created in Visual Studio (Contoso.Intrant.master), so change the reference within the home page.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0fYKsSi4ZXLhkWS89mpQhjnj9aYLneujG_TLiNPfc9teYTEcU1AX7LSwWpsdPCd9w2N0mjQZxrxSUQf0eBXyWn5pZRQGv6CJgSmlbkireCwnIHyWFaoOjDHqR67myi9LGNm1oxYl3bMlN/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+42+-+new+Contoso.Intranet.home.aspx+changing+the+master+page+reference.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0fYKsSi4ZXLhkWS89mpQhjnj9aYLneujG_TLiNPfc9teYTEcU1AX7LSwWpsdPCd9w2N0mjQZxrxSUQf0eBXyWn5pZRQGv6CJgSmlbkireCwnIHyWFaoOjDHqR67myi9LGNm1oxYl3bMlN/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+42+-+new+Contoso.Intranet.home.aspx+changing+the+master+page+reference.jpg" /></a><br />
<br />
<div class="alert">
<table>
<tbody>
<tr>
<th align="left"><strong>Note</strong></th>
</tr>
<tr>
<td>1 - Note that referencing the Masper Page directly within the source code of the Home page
allows me to create a customized part of the site dedicated to the visitors while preserving
the back-office pages from any customizations. (You don't need to do this for a publishing
site since there is already two Master Pages to do this).<br />
2 - For referencing the Master Page I should rather have declared:
~site/_catalogs/masterpage/contoso.intranet.master so as the package could be deployed
within any site collection.</td>
</tr>
</tbody>
</table>
</div>
<br />
<span style="color: #e9ab17;">2.8 Updating the Module element.xml file to prepare the registration of the pages
within the SharePoint libraries at the Feature activation time</span><br />
<br />
Now we have to specify the libraries Url where we want our pages to be registred when activating the feature. Here
is the code : <br />
<br />
<pre style="background-color: white; border: solid 1px silver; overflow: scroll; white-space: pre; width: 100%;"><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"><span style="color: #a31515; font-size: 9.5pt;">xml</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;"> </span><span style="color: red; font-size: 9.5pt;">version</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">=</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">"</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">1.0</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">"</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;"> </span><span style="color: red; font-size: 9.5pt;">encoding</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">=</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">"</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">utf-8</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">"</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;">?></span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-size: 9.5pt;"><o:p></o:p></span></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"><</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt;">Elements</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">xmlns</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">http://schemas.microsoft.com/sharepoint/</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">></span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;"><o:p></o:p></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> <</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt;">Module</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">Name</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">Module Pages</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">></span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;"><o:p></o:p></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> <</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt;">File</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">Path</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">Module Pages\Contoso.Intranet.master</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">Url</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">_catalogs/masterpage/Contoso.Intranet.master</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> /></span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;"><o:p></o:p></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> <</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt;">File</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">Path</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">Module Pages\Contoso.Intranet.Home.aspx</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </span><span style="background: white; color: red; font-family: "consolas"; font-size: 9.5pt;">Url</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">=</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">SiteAssets/Contoso.Intranet.Home.aspx</span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;">"</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> /></span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;"><o:p></o:p></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;"> </</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt;">Module</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt;">></span><span style="background: white; font-family: "consolas"; font-size: 9.5pt;"><o:p></o:p></span>
<span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt; line-height: 115%;"></</span><span style="background: white; color: #a31515; font-family: "consolas"; font-size: 9.5pt; line-height: 115%;">Elements</span><span style="background: white; color: blue; font-family: "consolas"; font-size: 9.5pt; line-height: 115%;">></span>
</pre>
and the Visual Studio screenshot:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvk5joNd4A_alpq0uNSMfyVplKOl2mRAjqeNg9TPjzSJPqPpSalc2R0tP05qLC5pmRhmgDbR_mmhoJma0NeK5YMXWZB9NpNeQfgS6LVsnYAC_fUYzqnKCHbpyVUhN-04aUvixoF_afUoRl/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+43+-+modifying+the+elements.xml.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvk5joNd4A_alpq0uNSMfyVplKOl2mRAjqeNg9TPjzSJPqPpSalc2R0tP05qLC5pmRhmgDbR_mmhoJma0NeK5YMXWZB9NpNeQfgS6LVsnYAC_fUYzqnKCHbpyVUhN-04aUvixoF_afUoRl/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+43+-+modifying+the+elements.xml.jpg" /></a><br />
<br />
Notice that I removed the reference to the .css file since we decided before (while doing the to do list) that we
will deploy the .css file by downloading it directly in the style library. <br />
<br />
<span style="color: #e9ab17;">2.9 Testing the deployment of the No-Code Sandboxed Solution (NCSS) within the
development environment</span><br />
<br />
Now, we are going to test if everything is deploying well with the solution we have just built. So, right click your
project in Visual Studio and locate "Deploy Solution" in the contextual menu. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjLymF1ZgYvBdnjj_RZN4U0HzbgycLMb8Z9eNzgtOlamNdN-OxEiSRPsTy7J0bu-1b_lQntUcpN63Ad-nH8JUCFlAH8i_FMIDUCGYoGW2VDfxXwnRmbC6is6MY_EJsGkCWLXYJ_jWsQRFd/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+44+-+deploying+the+solution.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjLymF1ZgYvBdnjj_RZN4U0HzbgycLMb8Z9eNzgtOlamNdN-OxEiSRPsTy7J0bu-1b_lQntUcpN63Ad-nH8JUCFlAH8i_FMIDUCGYoGW2VDfxXwnRmbC6is6MY_EJsGkCWLXYJ_jWsQRFd/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+44+-+deploying+the+solution.jpg" /></a><br />
<br />
Visual Studio deploys your solution in sandboxed mode, activates the feature and warns you that everything is ok.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirE-rlEYDn2Ayh0GvHBM_cRgtgwDCgCi27H-ltAe1Kg_1edbnoT0JRQUztD-8iQldOcyxrTBPBucGtacopiLFKXixGLJmvVb4uMQ_xl-2QG5yRncEF2m7kjVcdCMijOZ_s2oyzHCmNNSqK/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+46+-++solution+deployed.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirE-rlEYDn2Ayh0GvHBM_cRgtgwDCgCi27H-ltAe1Kg_1edbnoT0JRQUztD-8iQldOcyxrTBPBucGtacopiLFKXixGLJmvVb4uMQ_xl-2QG5yRncEF2m7kjVcdCMijOZ_s2oyzHCmNNSqK/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+46+-++solution+deployed.jpg" /></a><br />
<br />
Now we have to check that everything is really ok. So, first go to the site collection Solution Store to check if
the Solution is well deployed and activated. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqvds3LdE8F-nzg7UciAWjGd0aH24GokGZuXqy3uND2Ho0SsExo_ntrEYmLAVat4SmdREmaNYB1jHROsTx44Se5GATaJbOW5wPP3lQMTi0edqg1zn1FukhTByDQQc_UFe2mWgWPPnm3ODU/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+47+-++solution+deployed+-+site+collection+solution+store.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqvds3LdE8F-nzg7UciAWjGd0aH24GokGZuXqy3uND2Ho0SsExo_ntrEYmLAVat4SmdREmaNYB1jHROsTx44Se5GATaJbOW5wPP3lQMTi0edqg1zn1FukhTByDQQc_UFe2mWgWPPnm3ODU/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+47+-++solution+deployed+-+site+collection+solution+store.jpg" /></a><br />
<br />
Yes it is ! Now we are going to check if the Feature is well activated. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaxiJhVW3JjAljlUtEgz7NiFONoKCTiODJd4imlodoyOg-QYokU4PMvI0c4t9G9P2G_11fLFD1gwO2utbvf8aJSV3sLFYJYN9oTiwYASqnbsBWZHS-WGpzpWTSHbMSYHxthfdWrCQEbGS1/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+47+-++solution+deployed+-+site+collection+Features.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaxiJhVW3JjAljlUtEgz7NiFONoKCTiODJd4imlodoyOg-QYokU4PMvI0c4t9G9P2G_11fLFD1gwO2utbvf8aJSV3sLFYJYN9oTiwYASqnbsBWZHS-WGpzpWTSHbMSYHxthfdWrCQEbGS1/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+47+-++solution+deployed+-+site+collection+Features.jpg" /></a><br />
<br />
Yes it is. The feature is present and well activated ! Let's check if the master page is well registred in the
master pages gallery<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6PVnGUKIlp33hJsKgnpxh1eu0rc6jhQqMURlSj-XnM9uQcLtvngILVki3Lrj8bMZ-3Z-8BPI9ZonWkh2FX9XagpLTESHcd8hX-LnZlKdP1-gOha45PcwcXdLqJY_vWNvFUCvyE_KDda4v/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+48+-++solution+deployed+-+site+collection+master+pages+gallery.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6PVnGUKIlp33hJsKgnpxh1eu0rc6jhQqMURlSj-XnM9uQcLtvngILVki3Lrj8bMZ-3Z-8BPI9ZonWkh2FX9XagpLTESHcd8hX-LnZlKdP1-gOha45PcwcXdLqJY_vWNvFUCvyE_KDda4v/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+48+-++solution+deployed+-+site+collection+master+pages+gallery.jpg" /></a><br />
<br />
That's ok too. Good ! And last, the Home page in the Site Assets library...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw8R4zZggugkjiNUt72M0ujXfyBKGRJ536gMD7Ld73Qd4toOztXresGRXjHe9OMxhxampcOQ9D7Rbm1fZV6Qcpq3m7Z6tvKtzi2rZCrQtt_cNjUQhwYTBnSw8rXJkbFF7d7c894d3p2TO-/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+49+-++solution+deployed+-+site+Assets.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw8R4zZggugkjiNUt72M0ujXfyBKGRJ536gMD7Ld73Qd4toOztXresGRXjHe9OMxhxampcOQ9D7Rbm1fZV6Qcpq3m7Z6tvKtzi2rZCrQtt_cNjUQhwYTBnSw8rXJkbFF7d7c894d3p2TO-/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+49+-++solution+deployed+-+site+Assets.jpg" /></a><br />
<br />
That's good also. But when trying to display the home page we have this error : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0w7Ee5uPRiSrCXXL2dYSeAxynnXYDVjukbjlAmig2VIqLDpjtRGbp1WeT8Ds68p-ntc3rFMz4U74SbgzsAnNfABr-1Fzr3Jj_MdXR6ldSKS8d1rKdjrhGo5yKVODfJXnvSQOgRpdsuEVu/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+50+-+home+page+-++ressource+cannot+be+found+error.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0w7Ee5uPRiSrCXXL2dYSeAxynnXYDVjukbjlAmig2VIqLDpjtRGbp1WeT8Ds68p-ntc3rFMz4U74SbgzsAnNfABr-1Fzr3Jj_MdXR6ldSKS8d1rKdjrhGo5yKVODfJXnvSQOgRpdsuEVu/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+50+-+home+page+-++ressource+cannot+be+found+error.jpg" /></a><br />
<br />
But you can see what ressource is missing in the source code of the error page (<a href="http://mosshowto.blogspot.fr/2008/10/ressource-cannot-be-found-error.html">a trick I found 7 years ago and
that is still working!</a>) (By the way in the post you have also the trick to activate the displaying of
errors)<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI3VvprlelJ1ZAQU2MpvNESNQDIMdMyHrtuJPFmQZC_ob22m_wEltZc9P7hwjUoT6VRmQx4abu1yLfPXQ_3_4FbIPBhBJKrVbfcEhnOYycOYlNq3yWqIWqE2P1D9ggV3Mombb57U99rQtT/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+51+-+home+page+-++ressource+cannot+be+found+error+difference+Online+On+prem.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI3VvprlelJ1ZAQU2MpvNESNQDIMdMyHrtuJPFmQZC_ob22m_wEltZc9P7hwjUoT6VRmQx4abu1yLfPXQ_3_4FbIPBhBJKrVbfcEhnOYycOYlNq3yWqIWqE2P1D9ggV3Mombb57U99rQtT/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+51+-+home+page+-++ressource+cannot+be+found+error+difference+Online+On+prem.jpg" /></a><br />
<br />
So, the error page HTML source code says that "The file /_controltemplates/15/HelpPanel.ascx" is missing. This
perfectly normal. Why ? Because we pasted code used for SharePoint Online the 12th of October 2015 within a page
displayed by an older version of SharePoint 2013 on Premise. It is normal that elements are missing in my
development environment. <br />
By the way, if you check well the source code of SharePoint Online by opening the pages in webDAV mode you will
notice that the 12th of October 2015, SharePoint Online is already using the 2016 version of the product! Just
look:<br />
<br />
<pre style="background-color: white; border: solid 1px silver; overflow: scroll; white-space: pre; width: 100%;">
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: darkgreen; font-family: Consolas; font-size: 9.5pt;">-- _lcid="1033" _version="16.0.4524" _dal="1" --</span><span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: darkgreen; font-family: Consolas; font-size: 9.5pt;">-- _LocalBinding --</span><span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Page</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">language</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="C#"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">MasterPageFile</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="/sites/intranet/_catalogs/masterpage/contoso.intranet.master"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Inherits</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=16.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Register</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Tagprefix</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="SharePoint"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Namespace</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint.WebControls"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Assembly</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Register</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Tagprefix</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Utilities"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Namespace</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint.Utilities"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Assembly</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Import</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Namespace</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Assembly</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Name</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.Web.CommandUI, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
<span style="background: yellow; font-family: Consolas; font-size: 9.5pt;"><%</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">@</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: maroon; font-family: Consolas; font-size: 9.5pt;">Register</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Tagprefix</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="WebPartPages"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Namespace</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint.WebPartPages"</span> <span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: red; font-family: Consolas; font-size: 9.5pt;">Assembly</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-size: initial; color: blue; font-family: Consolas; font-size: 9.5pt;">="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"</span> <span style="background: yellow; font-family: Consolas; font-size: 9.5pt;">%></span>
</pre>
<br />
All the SharePoint .dll are from the 16.0.0.0 version ! So the code from SharePoint Online you paste in pages
deployed in a SharePoint 2013 environment cannot work. Not a big deal. We were able to check that the deployment was
ok. So let's deploy on SharePoint Online now. <br />
<br />
<span style="color: #e9ab17;">2.10 Deploying the solution within SharePoint Online</span><br />
<br />
Now is the time to deploy within SharePoint Online. Thus, go to the "debug" folder of your Visual Studio project,
and locate the .wsp file. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27uamBLGJEPULSvOhzo1CuSCIdnTmapsOqqUeKCsgZbzV6vQwxOybZSqwVDDJNszjLNHBl70Uq7r2eHk4gMjAtZM_cZ5aepTOfeIemV8OBNgXg1ajARskTYBoh2O5PXeN3AO8QMpltS2_/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+52+-++locating+the+NCSS.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27uamBLGJEPULSvOhzo1CuSCIdnTmapsOqqUeKCsgZbzV6vQwxOybZSqwVDDJNszjLNHBl70Uq7r2eHk4gMjAtZM_cZ5aepTOfeIemV8OBNgXg1ajARskTYBoh2O5PXeN3AO8QMpltS2_/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+52+-++locating+the+NCSS.jpg" /></a><br />
<br />
Then navigate to the Solution Store of your SharePoint Online environement and download the .wsp. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmwMaRshEXzUhK6CUewpyi3plHbZ_vBS5SrU4D7EH-GvmefTJI2Ac3oUfiMRZ0xgRpxVujRAz1fFosvspgGMyTQJpzKGVnXqHcUS7Q2Tduopqvx39Mftt1aikbmSseQJBZbdPtaMnOmJqE/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+53+-+uploading+a+NCSS+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmwMaRshEXzUhK6CUewpyi3plHbZ_vBS5SrU4D7EH-GvmefTJI2Ac3oUfiMRZ0xgRpxVujRAz1fFosvspgGMyTQJpzKGVnXqHcUS7Q2Tduopqvx39Mftt1aikbmSseQJBZbdPtaMnOmJqE/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+53+-+uploading+a+NCSS+within+SharePoint+Online.jpg" /></a><br />
<br />
Then, activate it and you should obtain the following screenshot: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRncRZ6nAGZpcQXtkyHWOfYhj_IjKrY2kfaaPTGDkxi70nWLcG6IPwYqfhkX4j9UGC77LEVJkD85G2VXjFX8pHX9170sgWBVrmeqhHn9byhnGVY9FXJ3uwHg0hhJSu8ISWs2pS-hrtorH6/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+54+-+NCSS+uploaded+and+activated+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRncRZ6nAGZpcQXtkyHWOfYhj_IjKrY2kfaaPTGDkxi70nWLcG6IPwYqfhkX4j9UGC77LEVJkD85G2VXjFX8pHX9170sgWBVrmeqhHn9byhnGVY9FXJ3uwHg0hhJSu8ISWs2pS-hrtorH6/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+54+-+NCSS+uploaded+and+activated+within+SharePoint+Online.jpg" /></a><br />
<br />
<span style="color: #e9ab17;">2.11 Testing the deployed solution within SharePoint Online</span><br />
<br />
Now, just check that the master page is well registred in the master pages gallery: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO5c3Rxkt49zvCNCiPDntW9I2Xu0TIQBa6zqb7SevAiiOTbGfInWzRUVkAuuiOaQUwwhsgii96407jPDVWf2zZF-NMSjZpFiblcQ4tVi2VNzY-PGgVE7LsX82gE4c5kYc-vfyeRRRgQo-k/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+55+-+Contoso.Intranet.master+deployed+and+ghosted+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO5c3Rxkt49zvCNCiPDntW9I2Xu0TIQBa6zqb7SevAiiOTbGfInWzRUVkAuuiOaQUwwhsgii96407jPDVWf2zZF-NMSjZpFiblcQ4tVi2VNzY-PGgVE7LsX82gE4c5kYc-vfyeRRRgQo-k/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+55+-+Contoso.Intranet.master+deployed+and+ghosted+within+SharePoint+Online.jpg" /></a><br />
<br />
and the same for the home page : <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtmbeSfBmCPKxHBeDZKoH4CVg2hr4zt6fEoynm65JZV_bc6QO6nCLW1w77LmJR1i9UCUs7uUoiaBH4HG14fkplk6M6oU_JRGVj2NOizgIAS5fqDcs3MT9BLUYLjtorABj868CpmzixRerP/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+56+-+Contoso.Intranet.home+deployed+and+ghosted+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtmbeSfBmCPKxHBeDZKoH4CVg2hr4zt6fEoynm65JZV_bc6QO6nCLW1w77LmJR1i9UCUs7uUoiaBH4HG14fkplk6M6oU_JRGVj2NOizgIAS5fqDcs3MT9BLUYLjtorABj868CpmzixRerP/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+56+-+Contoso.Intranet.home+deployed+and+ghosted+within+SharePoint+Online.jpg" /></a><br />
<br />
and check that the page is displaying well, not like in the SharePoint on premise environement: <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6reOQlfzgOBkFI93mosNpgcIE9ZYmp-_2w3xR1Xz-kZt8SXhI1LlE1-NF2ku9VHIEsyOseFy12TciZwPt1vf3MzAjah9UlOfQ_SkdwC9iYkbGPIDKM2mUd1wf6XX8DaIuXrFH7sbFQxqM/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+57+-+Contoso.Intranet.home+displaying+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6reOQlfzgOBkFI93mosNpgcIE9ZYmp-_2w3xR1Xz-kZt8SXhI1LlE1-NF2ku9VHIEsyOseFy12TciZwPt1vf3MzAjah9UlOfQ_SkdwC9iYkbGPIDKM2mUd1wf6XX8DaIuXrFH7sbFQxqM/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+57+-+Contoso.Intranet.home+displaying+within+SharePoint+Online.jpg" /></a><br />
<br />
Ok, that's good, although the css styles are missing because we haven't deployed them yet. Let's do it. Go back to
your Visual Studio project and locate the .css file. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdRfdnYoQwEHxqCv5UPkCqxY0ruZsnHbdW7IC5aI_zorQlLFwcGNykGj2dNtWPP7wi3ehmYGXC05Rp5ccHZAiZE5KPdn0N21VFybD2T-GghFp3SqcCVvyv6l9nTldtq4dK3A-7dLjp0kSk/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+58-++locating+the+css+file.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdRfdnYoQwEHxqCv5UPkCqxY0ruZsnHbdW7IC5aI_zorQlLFwcGNykGj2dNtWPP7wi3ehmYGXC05Rp5ccHZAiZE5KPdn0N21VFybD2T-GghFp3SqcCVvyv6l9nTldtq4dK3A-7dLjp0kSk/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+58-++locating+the+css+file.jpg" /></a><br />
<br />
Then drag and drop the file in the css folder of your SharePoint Online style library at the site collection level.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHirrTfZSNBKZLuiktuhVbRkhx3jzF3oMAsgC575MqeNPxbcaWR-87-HPr-wXcaQu290_cm3YWYGwEwJiIayINMLCh5M1Ae4RJl4daB_Nf0NKDMFjj6eqnvA7aYOITP79lCRqHByA-yIJT/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+59+-+uploading+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHirrTfZSNBKZLuiktuhVbRkhx3jzF3oMAsgC575MqeNPxbcaWR-87-HPr-wXcaQu290_cm3YWYGwEwJiIayINMLCh5M1Ae4RJl4daB_Nf0NKDMFjj6eqnvA7aYOITP79lCRqHByA-yIJT/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+59+-+uploading+the+css+file+within+SharePoint+Online.jpg" /></a><br />
<br />
You can see that the .css file has been properly added within the folder, but it is checked out so only
administrator will be able to see it. We have to check in it. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBlPFQrMTEA2pBzuMWASki6ScmG0Di-jF4Z8aYquqzFTg3F0GvQDgEZK5IlZZUCN8Afo_BD-W0UHTX6UWaHxVDqcF1Ee1cHCxFi04rq788c8cAKsdWqyE-jS0teJ5cah4OmNmM28yvKEu/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+61+-++checking+in+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBlPFQrMTEA2pBzuMWASki6ScmG0Di-jF4Z8aYquqzFTg3F0GvQDgEZK5IlZZUCN8Afo_BD-W0UHTX6UWaHxVDqcF1Ee1cHCxFi04rq788c8cAKsdWqyE-jS0teJ5cah4OmNmM28yvKEu/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+61+-++checking+in+the+css+file+within+SharePoint+Online.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoAjwOamOe4WD0K017DVvDj_b_PZiyp-_6Yo4rmU5PxCHGhhNT4X6lg3SDwUlab3Wg7I_LAECc3nU7gT4LVrgkorcMIm2ocya2IveECaHHErojhWb37BN5Ktdfy18n7nw57VcQXrVRr7mV/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+62+-++checking+in+the+css+file+within+SharePoint+Online.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoAjwOamOe4WD0K017DVvDj_b_PZiyp-_6Yo4rmU5PxCHGhhNT4X6lg3SDwUlab3Wg7I_LAECc3nU7gT4LVrgkorcMIm2ocya2IveECaHHErojhWb37BN5Ktdfy18n7nw57VcQXrVRr7mV/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+62+-++checking+in+the+css+file+within+SharePoint+Online.jpg" /></a><br />
<br />
When it's done, you finally can display the home page of your Intranet properly! <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwzfxIATsMzpndAyqpHucNm-r9X2WpmcWwGY8v87ApprFTpeUx0C1MTGKETXHCdJHk8XI2hCGlSlGxN2OL932VMtgSVfFG6r2_RYI3T3S6jJHt5EfCuULXFQPeQ2HgpOS4S0QZgmaZn7hG/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+63+-++New+Contoso+Branding+elements+perfectly+working.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwzfxIATsMzpndAyqpHucNm-r9X2WpmcWwGY8v87ApprFTpeUx0C1MTGKETXHCdJHk8XI2hCGlSlGxN2OL932VMtgSVfFG6r2_RYI3T3S6jJHt5EfCuULXFQPeQ2HgpOS4S0QZgmaZn7hG/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+63+-++New+Contoso+Branding+elements+perfectly+working.jpg" /></a><br />
<br />
And the page and the master page are this time perfectly ghosted because they were deployed by a .wsp and activated
by a SharePoint Feature. However, our work is not finished yet, because we have to do cleaning operations in our
SharePoint Online environment. <br />
By the way, if you take a look at the html source code of the page you can see how our SharePoint control
<sharepoint:cssregistration has rendered the HTML <Link> tag properly, placing the custom css just after
the SharePoint native ones...<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXSauN3YU4k2eak4zTmPlsHBUWckwFGvEPPRu0B0iuSOZzUu_HXqTBQMnU-3DV0PGJFfp7sR4MzCqXhmhbIJVkv6WXUnPZoTAiqjpqEtI4K1qv-Akcyw6q8KT0REJQtxxF0t6OH34AAcGw/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+64+-+CSS+registration+has+perfectly+mnaged+the+css.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXSauN3YU4k2eak4zTmPlsHBUWckwFGvEPPRu0B0iuSOZzUu_HXqTBQMnU-3DV0PGJFfp7sR4MzCqXhmhbIJVkv6WXUnPZoTAiqjpqEtI4K1qv-Akcyw6q8KT0REJQtxxF0t6OH34AAcGw/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+64+-+CSS+registration+has+perfectly+mnaged+the+css.jpg" /></a><br />
<br />
<div class="alert">
<table style="width: 100%px;">
<tbody>
<tr>
<th align="left"><strong>Note</strong></th>
</tr>
<tr>
<td>Note that you can also publish the No-Code Sandboxed Solution (.wsp) directly to SharePoint
Online. <a href="https://msdn.microsoft.com/en-us/library/hh370987.aspx">Here is the
official MSDN "How To"</a>. </td>
</tr>
</tbody>
</table>
</div>
<br />
<span style="color: #e9ab17; margin-left: 20px;">2.12 Cleaning our SharePoint Online environment</span><br />
<ul>
<li>deleting the old "unghosted" home page</li>
</ul>
First operation, let's delete the customized (unghosted in webDAV mode previously) Home.aspx page since we have now
the same page perfectly ghosted. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoPAbcDla4CVyIbrV9n2jvMxuhLPLWz7T5qc_9qI4icvhjk2KLHDmjxNDWuV2xunYiUwwejmHu5uCGtDhCgaqPldwtsEGenbsom8bE7J5ApUopKLeytS1PpokvDMjIwkHZazlNhhoaPx2S/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+65+-+deleting+the+home+unghosted+page.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoPAbcDla4CVyIbrV9n2jvMxuhLPLWz7T5qc_9qI4icvhjk2KLHDmjxNDWuV2xunYiUwwejmHu5uCGtDhCgaqPldwtsEGenbsom8bE7J5ApUopKLeytS1PpokvDMjIwkHZazlNhhoaPx2S/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+65+-+deleting+the+home+unghosted+page.jpg" /></a><br />
<ul>
<li>renaming the new "ghosted" home page</li>
</ul>
Secondly, we can now rename the ghosted Home page with the same name than the page (unghosted) we have just deleted.
You will see that not only the display name of the page has changed, but also the name in the URL. <br />
<br />
<div class="alert">
<table>
<tbody>
<tr>
<th align="left"><strong>Note</strong></th>
</tr>
<tr>
<td>Note that if you deactivate and reactivate the feature that has registered the page, you will
have a new home page again, you will be able to rename this page and by doing the same
operation again you will have a workaround for "provisioning" a lot of pages based on the
same template.</td>
</tr>
</tbody>
</table>
</div>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFZJRbXY_K12cgLptiZ8krUeVHNU3rkDy5vfGuGZhANApgEzM-daW_8z7-mFqkTgjBDz02vs-Au9Z4Psbph7c6yeDT4WtjYGSPllhVVXAUivsYn24OXkGhHT2PI4si1kMicT9Qa25VCJIl/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+66+-+new+home+ghosted+page+renamed.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFZJRbXY_K12cgLptiZ8krUeVHNU3rkDy5vfGuGZhANApgEzM-daW_8z7-mFqkTgjBDz02vs-Au9Z4Psbph7c6yeDT4WtjYGSPllhVVXAUivsYn24OXkGhHT2PI4si1kMicT9Qa25VCJIl/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+66+-+new+home+ghosted+page+renamed.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKf5Ev0cunHKGaGWUOsvYyy_hfxMAYNozlmsAxkZCmP3GOVFvjFvWVGW20bSZOf81FNH1SOtFX-SqBVLojt6YnUtXte4fjuxWL1Uji9h_u9t5idJP9s2Q9_ZnE4H1aXIGvxg2Ap-f1jQkG/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+67+-+new+home+ghosted+page+working+well.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKf5Ev0cunHKGaGWUOsvYyy_hfxMAYNozlmsAxkZCmP3GOVFvjFvWVGW20bSZOf81FNH1SOtFX-SqBVLojt6YnUtXte4fjuxWL1Uji9h_u9t5idJP9s2Q9_ZnE4H1aXIGvxg2Ap-f1jQkG/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+67+-+new+home+ghosted+page+working+well.jpg" /></a><br />
<br />
<ul>
<li>reseting the customized (unghosted) oslo.master to site definition</li>
</ul>
<br />
This is the last cleaning operation. Previously, we have modified the oslo.master Master Page using WebDAV protocol
and, as a result, this Master Page, that is a native page of SharePoint Online has been temporary placed in an
unghosted state. We have to fix this in order this native page recover its original uncustomized (ghosted) state.
<br />
<br />
First, we need the Url of the page. This is a trick to get it. Go to the Master Page Gallery of your SharePoint
Online site collection and display the properties of the oslo.master Master Page. <br />
You will have a link to the Master Page displayed so as you be able to copy it as a shortcut. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTGq_RzNTcNb5Awcnf5NsQV9C7UVlHSipVNotg-MmnqbfsKGI6T-xIY_NB18wTeLqxrsgSn4R0mrPkqPGaYlPLLJ_fBGg24ToBzShPZDuPahBg4lCo7O_6-lmpqzPzatj7pRVw5Dsw3bdE/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+68+-+reseting+oslo.master+to+site+definition+01.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTGq_RzNTcNb5Awcnf5NsQV9C7UVlHSipVNotg-MmnqbfsKGI6T-xIY_NB18wTeLqxrsgSn4R0mrPkqPGaYlPLLJ_fBGg24ToBzShPZDuPahBg4lCo7O_6-lmpqzPzatj7pRVw5Dsw3bdE/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+68+-+reseting+oslo.master+to+site+definition+01.jpg" /></a><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqXa2OccfhGN0z874FJW6dN0spRd32mO8IRy486P95ExGmiaou91uv1VoAWJZNdzWHcyidyQxKwXYPxqNaLkWBnrRuOb3faa3V-5RLsm5EKhUCoDowxGTaAMwQXeH1uHupITK1VYkPpouX/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+69+-+reseting+oslo.master+to+site+definition+02.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqXa2OccfhGN0z874FJW6dN0spRd32mO8IRy486P95ExGmiaou91uv1VoAWJZNdzWHcyidyQxKwXYPxqNaLkWBnrRuOb3faa3V-5RLsm5EKhUCoDowxGTaAMwQXeH1uHupITK1VYkPpouX/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+69+-+reseting+oslo.master+to+site+definition+02.jpg" /></a><br />
<br />
Then, go to the Site Settings of your Site Collection, and you will find a link under the "Site Actions" section
called "Reset to site definition". Click this link. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJQF1sy7vk_UWYv6fwB0OoOfzEFGvmJOEcBgSBBGdy818SmBImevicKisZTVYn5S2gIXdYWTjBr66HPPYGufBPcwFdR3JDKPMc28IGei1-aly9Pj0j1NUkb80DH90BuAYgcMi5_RswdtH1/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+70+-+reseting+oslo.master+to+site+definition+03.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJQF1sy7vk_UWYv6fwB0OoOfzEFGvmJOEcBgSBBGdy818SmBImevicKisZTVYn5S2gIXdYWTjBr66HPPYGufBPcwFdR3JDKPMc28IGei1-aly9Pj0j1NUkb80DH90BuAYgcMi5_RswdtH1/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+70+-+reseting+oslo.master+to+site+definition+03.jpg" /></a><br />
<br />
Paste the link to the customized oslo.master Master Page that is currently in your clipboard within the text-box.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR8DgabpTvR8E134YxayhH1RS9L6QvuHd99fQ11zft6Vb0nwBnc5KoEoJlg_pp7DNnbUuBtI6H1dXF3mtZpKpgC_QHW9njT-dDcf__QK5CcJrfuAjAewfWpBtFQvBx_L-tMMf1Kp74i9Vy/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+71+-+reseting+oslo.master+to+site+definition+03.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR8DgabpTvR8E134YxayhH1RS9L6QvuHd99fQ11zft6Vb0nwBnc5KoEoJlg_pp7DNnbUuBtI6H1dXF3mtZpKpgC_QHW9njT-dDcf__QK5CcJrfuAjAewfWpBtFQvBx_L-tMMf1Kp74i9Vy/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+71+-+reseting+oslo.master+to+site+definition+03.jpg" /></a><br />
<br />
You are warned that you could lose all the modifications performed outside the browser (aka in WebDAV mode,
SharePoint Designer and so on...). We can lose these modifications because we have durably stored them in a package
and they are currently deployed in our SharePoint Online site via the .wsp (No-Code Sandboxed Solution or NCSS).
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYEIQA4c77HHn_7vVKS2W325vk9uEu1JYiHjcBsHrg_LrTSNo6gitcctKr7g0cHFTFYF9pNY8oXA8T2KrePZJT7VOJeoRUoc6J1FxxeS3rAzQ9Yf6loaLpnqN7vq3RrahXH6hG72Tnsw_E/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+72+-+reseting+oslo.master+to+site+definition+05.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYEIQA4c77HHn_7vVKS2W325vk9uEu1JYiHjcBsHrg_LrTSNo6gitcctKr7g0cHFTFYF9pNY8oXA8T2KrePZJT7VOJeoRUoc6J1FxxeS3rAzQ9Yf6loaLpnqN7vq3RrahXH6hG72Tnsw_E/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+72+-+reseting+oslo.master+to+site+definition+05.jpg" /></a><br />
<br />
After having reset the oslo.master Master Page to its original template, if we reopen it using WebDAV protocol we
notice that all the custom styles that we have placed within it before were totally removed!<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTmNX8kgb0RXi03yr3tTY7bHQCqw433IcuWp7Op2kk4TMIocgJQrn6d1fq3S6pgAaDkSkMk7gAVzbNjew1ZDto2b8r2bYyAv-XNJgIjS6BZjJuTPgeGwkO0csGfd6pLPIUzuGU6u5aOgXf/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+73+-+oslo.master+has+been+reset+to+site+definition.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTmNX8kgb0RXi03yr3tTY7bHQCqw433IcuWp7Op2kk4TMIocgJQrn6d1fq3S6pgAaDkSkMk7gAVzbNjew1ZDto2b8r2bYyAv-XNJgIjS6BZjJuTPgeGwkO0csGfd6pLPIUzuGU6u5aOgXf/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+73+-+oslo.master+has+been+reset+to+site+definition.jpg" /></a><br />
<br />
Of course close the page open in WebDAV mode <b>without saving it</b> or it will be customized again...<br />
<br />
<ul>
<li>Making Home.aspx the actual Home Page of our Site</li>
</ul>
Now we have to set the Home.aspx page as the Home Page of our site. You have this feature in the Page Ribbon.
Just click the button. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmfd1AXs86kaJOZPDLNENZD6GF7BJm2RsP-yJpQqelf1rweb8psmKTiaiDhQ4JJTyXPjiyRs98Cr7UrPqohIDaWkC_ZTUol6uc4U00_PyVxIsW5iDzOCvNzBr3n9ynRNHIU8Cm2LVbmsrA/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+74-+make+the+ghosted+home.aspx+page+the+home+page+of+the+site.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmfd1AXs86kaJOZPDLNENZD6GF7BJm2RsP-yJpQqelf1rweb8psmKTiaiDhQ4JJTyXPjiyRs98Cr7UrPqohIDaWkC_ZTUol6uc4U00_PyVxIsW5iDzOCvNzBr3n9ynRNHIU8Cm2LVbmsrA/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+74-+make+the+ghosted+home.aspx+page+the+home+page+of+the+site.jpg" /></a><br />
<br />
Now, if you type the Url of your site within a browser you will land directly on this Home page. <br />
<br />
<ul>
<li>Last test for the Home Page </li>
</ul>
We have finally to test if the Home page is really working well and if we can add text to it... Good move
because I noticed that custom styles have partially disturbed the proper functioning of the script editor Web Part
and I had to add a <DIV> tag to tune the margin of the rendered text. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMfL7fs0tkSPyOzVtUNwOSBcTwrrPqUsgTwrkjUBY-9UYqaMBVzBf32GgyMtCH8_PfBdvn62uzPW9HSIXMPubih4RUBvn8b6vJm5figem0xxKhQjQYV1Nc6LGxLkkWkKU2nAVnl2EJ3hU1/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+75-+checking+if+the+home+page+is+working.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMfL7fs0tkSPyOzVtUNwOSBcTwrrPqUsgTwrkjUBY-9UYqaMBVzBf32GgyMtCH8_PfBdvn62uzPW9HSIXMPubih4RUBvn8b6vJm5figem0xxKhQjQYV1Nc6LGxLkkWkKU2nAVnl2EJ3hU1/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+75-+checking+if+the+home+page+is+working.jpg" /></a><br />
<br />
<br />
But I finally could display a satisfying message within our Home page based on a custom but ghosted Web Part page, a
custom but ghosted Master Page, custom Logo and .css files, with all that properly deployed!<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vcKMEttnkxAiaMSQyVmygYxDABqBAeUisgPo6XWwTychPYYJHEXwOq2rx9yCjDhsOjrUjVeSSzPT6I742ZvfCUOe-Cb85tqS8sGAlhiayG2KHynMrXVYEGnmAua3tNSzQjvhcnuXISTO/s1600/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+76-+the+home+page+is+working+despite+a+littlle+css+problem.jpg" imageanchor="1"><img border="0" class="screenshot-standard" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vcKMEttnkxAiaMSQyVmygYxDABqBAeUisgPo6XWwTychPYYJHEXwOq2rx9yCjDhsOjrUjVeSSzPT6I742ZvfCUOe-Cb85tqS8sGAlhiayG2KHynMrXVYEGnmAua3tNSzQjvhcnuXISTO/s1200/Branding+SharePoint+Online+Team+Site+-+Marc+Charmois+-+76-+the+home+page+is+working+despite+a+littlle+css+problem.jpg" /></a><br />
<br />
<span style="color: red;">Updated 2015 October 16</span><br />
<br />
I finally fixed the css for a better displaying of the pages: <br />
<br />
#siteIcon{<br />
margin-top:0px;<br />
}<br />
#titleAreaBox{<br />
margin-top:0px;<br />
margin-left:20%; <br />
margin-right:20%;<br />
background-color:rgba(242, 242, 242, 1);<br />
}<br />
#titlerow{<br />
background-color:rgba(242, 242, 242, 1);<br />
}<br />
/*.noindex, */<br />
.ms-core-listMenu-horizontalBox{<br />
margin-top:30px; <br />
margin-left:-200px;<br />
}<br />
.ms-breadcrumb-box {<br />
padding-top: 5px;<br />
padding-bottom: 5px;<br />
height:30px;<br />
}<br />
<br />
#SearchBox{<br />
margin-left:200px;<br />
margin-right:-50px;<br />
}<br />
#suiteBarDelta{<br />
margin:0px;<br />
margin-top:0px; <br />
}<br />
#DeltaPlaceHolderSearchArea{<br />
padding-top:45px;<br />
}<br />
.ms-srch-sb > input {<br />
width: 140px;<br />
}<br />
<br />
<br />
<span style="color: #e9ab17;">2.12 The pros and cons of using No-Code Sandboxed Solutions (aka NCSS) for customizing
SharePoint Online</span><br />
<br />
<ul>
<li>The Pros<br />
<ul>
<li>Compared with Add-Ins: Although the new Add-Ins model for SharePoint (formerly called Apps) is
documented by Microsoft as the the recommended way for customizing SharePoint, <span style="color: red; font-weight: bold;">the No-Code Sandboxed Solutions (NCSSs) are still
supported</span>. More than that, you can see in <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">the official MSDN
documentation</a> that among the scenarios recommended by Microsoft for using No-Code Sandboxed
Solutions instead of Add-Ins (formerly called Apps), Branding of SharePoint Sites is one of
them:<br />
<br />
[... SharePoint users often want to give their SharePoint sites, including their SharePoint Online
sites, a custom appearance with their own colors, styles, layouts, and logos. This is generally
easier to do with NCSSs than with SharePoint Add-ins.<br />
...] MSDN <a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx#Anchor_2">
SharePoint Add-ins compared with SharePoint solutions</a><br />
<br />
Notice that the documentation was updated <span style="color: red; font-weight: bold;">August 12,
2015</span>. Here is <a href="http://blogs.msdn.com/b/sharepointdev/archive/2014/01/14/deprecation-of-custom-code-in-sandboxed-solutions.aspx">another
interesting link</a> on this topic: There is a big confusion currently between the SharePoint
2010 Sandboxed Solutions (not supported) and the No-Code Sandboxed Solutions (still
supported).<br />
<br />
But NCSSs compared with Add-Ins are not only an easier way for branding a SharePoint Online site.
Regarding branding, Add-Ins are more limited: <br />
<br />
[...<br />
A SharePoint Add-in has declarative control over the appearance of only its own add-in web. For the
host web, it can declaratively add only ribbon buttons and menu items (and add-in parts). Any other
changes to a host web or its parent site collection, tenancy, or on-premisesSharePoint web
application has to be done with code or script that uses one of the SharePoint's client object
models. For example, new icons or CSS files would have to be programmatically deployed. This code
could be run from the add-in itself after it is installed, or it could run in the add-in
installation event handler. But it would take a considerable amount of work to create this code.
<br />
In addition, the add-in would need site collection-scoped permissions to change any websites outside
its own add-in web and host web, and it would need tenant-scoped permissions to change more than
just its parent site collection. A branding NCSS, however, can be deployed and activated to any site
collection; and it could consist of only a few purely declarative components.<br />
...] (<a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx#Anchor_2">MSDN</a>)<br />
<br />
</li>
<li>Compared with customizations done using WebDAV protocol: your customizations are easily maintainable
and there is few risks to lose them because they were developped with Visual Studio, so they can
easily be stored in a Source Code Control System (like Team Foundation Server) and they are all
gathered within a single or a few packages: .wsp based on No-Code Sandboxed Sollutions (NCSS) <br />
</li>
<li>Compared with customizations done using WebDAV protocol: With a deployment using No-Code Sandboxed
Solutions, the customized pages are not stored in the SharePoint content databases like these
customized using the WebDAV protocol, they seem to be stored under this location within all the
SharePoint servers of a SharePoint Farm: <br />
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\<br />
Some says that using pages based on templates stored within the file systems of the SharePoint
servers leads to a gain of performances. I am not sure if it is true or not.</li>
</ul>
</li>
</ul>
<br />
<ul>
<li>The Cons </li>
<ul>
<li>Compared with customizations done using WebDAV protocol: It's longer (you can realize that just by
comparing the lists of necessary operations to both approaches as described in this article). It
requires developers knowing SharePoint well so it's also more expensive. <br />
</li>
<li>Compared with Add-Ins (formerly called Apps): As your customized pages are not based on a OOTB
SharePoint template anymore, <span style="color: red;">if any update of the SharePoint templates is
performed by Microsoft</span>, these updates won't be taken into account by your customized page.
<span style="color: red;">You will miss new features of the product or maybe even lose current ones
depending on the Microsoft updates.</span> So you might perform sometimes unexpected maintenance
operations for recovering all the features of the SharePoint product. (<span style="color: red;">it
might not be the case with custom master pages based on the use of the Design Manager with which you
can convert an.html file into a SharePoint 2013 master page, a .master file</span>. I have to check
this more seriously. By the way, I planned to redo the same post using the SharePoint Publishing
Features).<br />
</li>
</ul>
</ul>
<br />
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">
3 - Branding a SharePoint Online team site using Add-ins (formerly called Apps)</div>
<br />
As said at the beginning of the post, I have explained the two first approaches that are the classical ones. I will
dedicate a specific post (to be published soon) for describing all the steps necessary to carry out the last
approach (Add-Ins). But don't forget that Add-ins regarding this topic (SharePoint Online Branding) and until
further notice from Microsoft, are just an alternate choice with its own pros and cons.<br />
As a matter of fact, Microsoft recommends to use Add-Ins whenever you can, but recommends NCCSs for branding as the
easiest way to do it. (<a href="https://msdn.microsoft.com/en-us/library/office/jj163114.aspx">MSDN: SharePoint
Add-ins compared with SharePoint solutions</a>)<br />
<br />
Regarding this approach, you can already check the material available on the Office 365 Developer Patterns and
Practices: <br />
<br />
<a href="https://channel9.msdn.com/Blogs/Office-365-Dev/Alternate-CSS-and-set-site-logo-Office-365-Developer-Patterns-and-Practices">Alternate
CSS and set site logo</a><br />
<br />
<a href="https://github.com/OfficeDev/PnP/tree/master/Samples/Branding.AlternateCSSAndSiteLogo">Or directly the
associated source code for the Add-In</a><br />
<br />
You will notice that in the Office 365 Developer Patterns and Practices sample, the Add-In :<br />
<ul>
<li>Change programmatically (Imperative approach) the logo and the CSS references for the site<br />
<pre class="code-standard">
web.AlternateCssUrl = web.ServerRelativeUrl + "/SiteAssets/contoso.css";
web.SiteLogoUrl = web.ServerRelativeUrl + "/SiteAssets/pnp.png";
web.Update();
web.Context.ExecuteQuery();
</pre>
</li>
<li>Upload programmatically (Imperative approach) the logo and the CSS files for the site<br />
<pre class="code-standard">
// Use CSOM to upload the file in
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(cssFile);
newFile.Url = "contoso.css";
newFile.Overwrite = true;
Microsoft.SharePoint.Client.File uploadFile = assetLibrary.RootFolder.Files.Add(newFile);
web.Context.Load(uploadFile);
web.Context.ExecuteQuery();
// Get the path to the file which we are about to deploy
string logoFile = System.Web.Hosting.HostingEnvironment.MapPath(string.Format("~/{0}", "resources/pnp.png"));
// Use CSOM to upload the file in
newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(logoFile);
newFile.Url = "pnp.png";
newFile.Overwrite = true;
uploadFile = assetLibrary.RootFolder.Files.Add(newFile);
web.Context.Load(uploadFile);
web.Context.ExecuteQuery();
</pre>
</li>
</ul>
<br />
Thus, that leads to finally examine the pros and cons of using Add-Ins for branding a SharePoint Online team
site:<br />
<ul>
<li>The pros <br />
<ul>
<li>Compared with NCSSs, <span style="color: red;">no impacts regarding Microsoft updates</span>:<br />
As Add-Ins are using imperative approach (doing things programmatically) the OOTB templates of
SharePoint (Web Part Page Templates, Page Layouts, default.aspx page, Master Pages) are preserved so
as any update from Microsoft regarding these templates will have no impacts on the customizations
performed using Add-Ins. That is to mean: <span style="color: red;">no custom Master Page anymore, no
CAML anymore, ever!</span><br />
</li>
</ul>
</li>
<li>The cons <br />
<ul>
<li>Compared with NCSSs: <span style="color: red;">NCSSs are more powerful</span>: <br />
As Add-Ins are using imperative approach (doing things programmatically) and NCSSs can use both
imperative (Client side of course with <a href="https://msdn.microsoft.com/en-us/library/office/jj163201.aspx">SharePoint JavaScript
library code</a>) and declarative approach (modifying HTML, CSS within the custom templates and
CAML for deploying and registering these custom templates in the libraries), <span style="color: red;">there are numerous things that you can do with NCSSs that you cannot do using
Add-Ins. That is to mean: custom Master Pages, custom pages, with all the HTML and the server
controls you want within the custom pages</span>. <br />
</li>
<li>Compared with NCSSs: Add-Ins require more time and more knowledge: <br />
Add-In model is completely new and different from classical approaches, thus technical team will
have to enhance knowledge to be really comfortable with these new approaches. As said in the MSDN
documentation when using Add-Ins remote imperative approach "it would take a considerable amount of
work to create this code".<br />
Not only the SharePoint team will be involved, but also people working in the infrastructure and
network areas because setting the necessary things regarding network and authentication for getting
Add-ins work properly in a company requires also time and knowledge. <br />
</li>
</ul>
</li>
</ul>
<div style="color: #e9ab17; font-weight: bold; margin: 1px 0px; padding-bottom: 10px; padding-left: 13px; padding-right: 0px; padding-top: 10px;">
4 - Branding a SharePoint Online team site using a customized Site Page and the SharePoint JavaScript Object
Model</div>
<br />
As said at the beginning of that post, there is also a fourth approach that mixes all the ones we have examined.
Roughly, you open a Web Part page of the SharePoint Online team site using WebDAV protocol, and you paste within the
code source of the page the instructions to change the css, logo, and Master Page of the site based on the
SharePoint JavaScript Libraries. <br />
Doing things that way, you are compliant with the new recommendations of Microsoft (avoid creating custom templates)
but you don't have to go trough the steps needed to package and deploy an Add-In that can be expensive in a matter
of time an knowledge. <br />
<br />
Here is the special post dedicated to this topic: <a href="http://mosshowto.blogspot.fr/2015/10/branding-sharepoint-online-javascript.html">Branding a SharePoint
Online team site using the SharePoint JavaScript Object Model</a><br />
<br />
<br /></div>
</div>
Marc Charmoishttp://www.blogger.com/profile/15609021917135631768noreply@blogger.com1