Tuesday, September 19, 2017

PowerShell Runbook to auto start and shut down Azure VM in a resource management group

Last post listed the sample code to start and shut down Azure VM remotely.

Here is the PowerShell runbook script which can be scheduled in Azure.

This is more stable, simpler and easier to manage.



$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID `
  -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint

Write-Output "Connection established."

$vmname = 'AZ532-test1'
$VMDetail = Get-AzureRMVM -ResourceGroupName $ResourceGroupName -Name $VmName -Status
$vmPowerstate = $VMDetail[1].Code
Write-Verbose "vmPowerstate: $vmPowerstate"

if ($vmPowerstate -like "PowerState/running"){
write-host "VM '$vmname' is ""$vmPowerstate"". Skip."
}
else{
write-host "Starting VM '$vmname'"
Start-AzureRMVM -ResourceGroupName $ResourceGroupName -Name $VmName -Verbose
}

if ($vmPowerstate -like "PowerState/running"){
write-host "Stopping VM '$vmname'"
Stop-AzureRMVM -ResourceGroupName $ResourceGroupName -Name $VmName -Verbose -Force
# }
# else{
write-host "VM '$vmname' is ""$vmPowerstate"". Skip."
# }

Write-Output "VM $vmname is started."

==============

Azure classic VM is similar:

$ConnectionAssetName = "AzureClassicRunAsConnection"
$connection = Get-AutomationConnection -Name $connectionAssetName        
Write-Verbose "Get connection asset: $ConnectionAssetName" -Verbose
$Conn = Get-AutomationConnection -Name $ConnectionAssetName
if ($Conn -eq $null)
{
    throw "Could not retrieve connection asset: $ConnectionAssetName. Assure            that this asset exists in the Automation account."
}

Write-Output "Connection established."

$CertificateAssetName = $Conn.CertificateAssetName
Write-Verbose "Getting the certificate: $CertificateAssetName" -Verbose
$AzureCert = Get-AutomationCertificate -Name $CertificateAssetName
if ($AzureCert -eq $null)
{
    throw "Could not retrieve certificate asset: $CertificateAssetName.       Assure that this asset exists in the Automation account."
}

Write-Verbose "Authenticating to Azure with certificate." -Verbose
Set-AzureSubscription -SubscriptionName $Conn.SubscriptionName -SubscriptionId $Conn.SubscriptionID -Certificate $AzureCert 
Select-AzureSubscription -SubscriptionId $Conn.SubscriptionID

$vmname = 'hvEF4'
$vm = Get-AzureVM | Where-Object { $_.Name -eq $vmname }
write-host "AzureVM: "
$vm | fl *

# if ($vm.PowerState -eq "Started"){
# write-host "Stopping VM '$vmname'"
# $vm | Stop-AzureVM -Force
# }
# else{
# write-host "VM '$vmname' is ""$($vm.PowerState)"". Skip."
# }

if ($vm.PowerState -eq "Started"){
write-host "VM '$vmname' is ""$($vm.PowerState)"". Skip."
}
else{
write-host "Starting VM '$vmname'"
$vm | Start-AzureVM
}

write-host "done."

Thursday, September 14, 2017

PowerShell script sample code to auto start and shut down Azure VM in a resource management group

There are quite a lot of changes in RMVM access API in the last two years. Here is some sample code which works well at the moment (2017-09-14).

Hopefully they can save you some time.



1. Install AzureRM module

script: Install-Module -Name AzureRM

2. Check PowerShell version and AzureRM module version

script: $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  1715

script: (get-module azurerm).Version

Major  Minor  Build  Revision
-----  -----  -----  --------
4      3      1      -1

3. Import AzureRM module

script: Import-Module AzureRM

4. Log in without prompt window

First we need to create a file to store the context information.

Login-AzureRmAccount

$Global:_ContextFilePath = "c:\azure.user.ericfang@outlook.com.ctx"
Save-AzureRmContext -Path $Global:_ContextFilePath -Force 

Then we can import the context file to avoid input user name and password manually.

Import-AzureRmContext -Path $Global:_ContextFilePath

5. Get the RM VM

$vmname = 'vm name'
$VMDetail = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VmName -Status | Select-Object -ExpandProperty StatusesText | convertfrom-json
$vmPowerstate = $VMDetail[1].Code

6. Start VM

if ($vmPowerstate -like "PowerState/running"){
write-host "VM '$vmname' is ""$vmPowerstate"". Skip."
}
else{
write-host "Starting VM '$vmname'"
Start-AzureRMVM -ResourceGroupName $ResourceGroupName -Name $VmName -Verbose
}

7. Or, shut it down (deallocate it)

if ($vm.PowerState -like "PowerState/running"){
write-host "Stopping VM '$vmname'"
Stop-AzureRMVM -ResourceGroupName $ResourceGroupName -Name $VmName -Verbose -Force
}
else{
write-host "VM '$vmname' is ""$vmPowerstate"". Skip."
}

Done.

PS: I scheduled the script in windows task scheduler to shut down all dev VMs in the evening. That can save a lot in case I forgot to shut them down manually.

PS 2:

Below is the script to start or stop classic Azure VM.

Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Azure.psd1"

# Get-AzurePublishSettingsFile

$publishsettings = 'e:\EricFang\Visual Studio Ultimate with MSDN-9-16-2016-credentials.publishsettings'

write-host "AzureSubscription: "
Import-AzurePublishSettingsFile $publishsettings

Select-AzureSubscription -SubscriptionId "YOUR SUBSCRIPTION GUID STRING"

$vmname = 'hvEF4'
$vm = Get-AzureVM | Where-Object { $_.Name -eq $vmname }
write-host "AzureVM: "
$vm | fl *

if ($vm.PowerState -eq "Started"){
write-host "VM '$vmname' is ""$($vm.PowerState)"". Skip."
}
else{
write-host "Starting VM '$vmname'"
$vm | Start-AzureVM
}

# $vm | Stop-AzureVM -Force

write-host "done."

Tuesday, July 4, 2017

Confusion and complains about Office 365

I am learning Office 365. There are many brilliant ideas in this platform, but also something annoying to me.

Below is my thoughts so far.  It will be keep updated.

[20170704]

1. Microsoft Teams really should be part of "Skype for Business", instead of a separate product.

[update 20170919] Two weeks ago, Microsoft announced that "Skype for Business" is emerged into Microsoft Teams. Great!

2. Documents should not be allowed to be copied from SharePoint Sites to "Teams Files".

It's much better to just create a file link in Microsoft Teams.

3. Outlook Group should be renamed as "Shared Inbox".

The details are described in this post

4. Yammer should be part of SharePoint site, instead of a separate product.

5. All documents should be forced to store in SharePoint Document Library.

In other tools (apps), the documents should be attached at a "file link".

[update, 20170722]

6. Unified API

For example, developers should be able to connect to different APPS by one API command.

[update, 20170726]

7. Add "Fast List" to SharePoint Online

"Fast List" needs to be as fast as SQL table, so all Office 365 items, including conversations, calendar events, etc. can all be stored in SharePoint Online.

[update, 20170731]



8. SPFX solution need "site collection" level deployment scope

"For SharePoint Framework solutions, there is only one deployment scope: tenant wide. Once added, and enabled, in the App Catalog, the SharePoint Framework solution will be available to all Site Collections."

https://github.com/SharePoint/sp-dev-docs/blob/master/docs/spfx/enterprise-guidance.md#sharepoint-framework-deployment-scopes


Friday, June 23, 2017

When should we use "Office 365 Groups"?

[updated regarding "Group Identity", 2017-07-04]

There are quite a lot of posts (such as here, here, and here) trying to explain what "Office 365 Groups" is. But, after reading them, I am still confused.

"Office 365 Groups" covers many areas: Azure AD, permission management, document depository (SharePoint sites), email (Exchange Online), group chat (Microsoft Teams), Yammer, etc. But,
  • When should Group be used?
  • Should we convert existing Email Distribution List into Group automatically, during the migration to Office 365?
  • Should we allow users to create new Group when they believe it is necessary?
  • Should we use Group Site to replace normal "Team Site"?
  • Should we create a Group for a new project?
  • Can one user belong to more than one Group?
After months of investigation, finally, I got my own conclusion. However, it is so faraway from the mainstream opinion, it even shocked myself!

There is only one principle: Office 365 Group should be based on basic "Group Identity Job Role".

Why? Because Group is designed to conquer the challenge of communication around group. Let me explain it through an use two cases here.

1. Communication between a person and a team

A user, let's say, Tom, needs help from DBA team to fix a database issue.

Obviously Tom doesn't care which member of the DBA team can help, and he just want the problem get resolved. The procedure may take months, existing DBA member may takes annual leave or even resign, new DBA may join the team at anytime. The communication between Tom and DBA team should not be affected by the those events, and it happens in many apps, such as SharePoint, Yammer, Outlook, Microsoft Teams, etc.

In other words, Tom wants to talk to DBA team, instead of any specific DBA, without the obstacles of permission management, information sharing, action history tracking.

That's why we need Group. Group should only be created for the bottom level, most basic organisation unit, just above individual user.

We should create a Group for DBA team (if there is more than one DBA in the team, and they all look after all databases), but not for IT department (because there is no such job role called "IT staff").

2. Communication in a team which needs to be shared across the whole team

For small projects, if it needs a lot of communication and those communication need to be shared across the whole team, then, it's better to create a group for it.

So, group members can use different tools to talk to each other, and don't need to worry about permission management or missing relevant project information.

=========

Now, it's easy to answer the previous questions.
  • When should it be used?
For each job role, if there are more than one person share the same responsibility, we should create a Group for them.

Normally it's just a few users, but, in some special case, for a role like "help desk", there could be more than 30 people.
  • Should we convert existing Email Distribution List into Group automatically, during the migration to Office 365?
No.

Unless the DL is created exactly for a job role.
  • Should we allow users to create new Group when they believe it is necessary?
No.
Users should contact Office 365 administrators to create it.
  • Should we use Group Site to replace normal "Team Site" during migration (from On-Premise to Office 365)?
No.

Unless the existing team site is created exactly for a job role.
  • Should we create a Group for a new project?
It depends.

Normally it's needed for small projects.
  • Can one user belong to more than one Group?
Normally, no.
Unless he/she happens to take two roles in two teams.

I know many people have different thoughts about "Office 365 Groups". Any comments are welcome!

PS 1: Microsoft Teams are perfect Application for Office 365 Group. We can create a new team/channel for each topic/task.

PS 2: Microsoft Teams really should be part of "Skype for Business".

PS 3: Documents should not be copied from SharePoint Sites to "Teams Files". It's much better to just create a file link in Microsoft Teams.

Wednesday, May 31, 2017

Pause workflow instances between 8pm to 6am

Servers are busy at midnight. Data backup, data synchronization, report building ...... keep the storage system and network busy, and databases may get locked up from time to time..

That's bad to those SharePoint workflows being triggered at night. Sometimes they would simply stop working and throw out errors.

Below is how I resolve this problem in Workflow 2010 and 2013.


Tuesday, May 30, 2017

Workflow(2010) need to be triggered twice after being published or after SharePoint server (2013) is rebooted

There are more than 200 site collections in Production environment. Many of them have SharePoint Designer workflows (declarative workflows). No customized activity get involved.

Recently users reported that a few workflows could not get triggered. But this problem only happened intermittently, and only 2010 workflow have this issue..

I did some test. They were right: I have to trigger the workflow twice to make it work, if the workflow got re-published, of if the SharePoint Server 2013 is rebooted.

There was not specific error message in ULS or Windows Events log, and the problem only appears in two site collections.

That's hard for trouble shooting.

My first guess: some site collection level feature is corrupted. The feature should be related to Workflow 2010. The most famous one is "Microsoft Office Server workflows" ("OffWFCommon", c9c9515d-e4e2-4001-9050-74f980f93160).

The PowerShell script below shows that the feature is activated properly.

$site = get-spsite $url
Get-SPFeature -Site $site -Limit All |?{$_.DisplayName -match "OffWFCommon"} | select *

What the problem could be? After hours of struggling, finally I found how to fix it: disable this site collection feature, and then rebuild the workflow.

(Thanks for the "copy and paste" functionality in SharePoint Designer, to rebuild a workflow is not as hard as before.)

Once the feature is disabled, we cannot modify the workflow initialization form any more. But, in most of cases, that’s not a problem.

Why this can fix the problem? I have no idea.

Please share your insight in comments if you know the root cause.  Many thanks!

PS: In SharePoint 2010, if this feature is disabled, then workflow will not be triggered. I haven't test it in SharePoint 2016 yet.

Thursday, May 18, 2017

MIM 2016 - Trouble Shooting - All users are filtered?

After the installation and configuration of MIM 2016 following this link, I noticed that no users can be synced from AD to SharePoint User Profile store. The Synchronization Service Manager shows the screenshot below.


All users fall into "Connectors without Flow Updates", and got filtered during syncing.

To fix that is easy: add a join rule for "user"("Data Source Object Type").


I am quite surprised that this is not added to the Step By Step Installation User Guide.