Powershell script in C# code under azure web job error

Brass Contributor

when i try to execute powershell script using the powershell object in c# code it runs ok on my desktop in visual studio but when i deploy the samme code on azure as web job then there is another problem and it breaks.

Code : 

            PowerShell ps = PowerShell.Create();
            InitialSessionState initialSession = InitialSessionState.CreateDefault();
            initialSession.ImportPSModule(new string[] { "Microsoft.Online.SharePoint.PowerShell" });
            initialSession.ImportPSModule(new string[] { "Microsoft.SharePoint.Client" });
            initialSession.ImportPSModule(new string[] { "Microsoft.SharePoint.Client.Runtime" });
            
            Runspace rSpace = RunspaceFactory.CreateRunspace(initialSession);
            rSpace.Open();
            RunspaceInvoke invoker = new RunspaceInvoke(rSpace);

            const string connectScript = " $AdminUrl = \"https://tenant-admin.sharepoint.com\" \r\n $UserName = \"user@tenant.onmicrosoft.com\" \r\n $Password  = \"password\" \r\n $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force \r\n $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $SecurePassword \r\n Connect-SPOService -Url $AdminUrl -Credential $Credentials \r\n Get-SPOSite -Detailed -Limit All | select * " ;

            Console.WriteLine("Powershell execution start");
            //const string getSiteScript =  "..\\..\\GetAllSiteColectionOnlineDetails.ps1";             
            var sites = invoker.Invoke(connectScript);  


Error in webjob logs: 

[05/02/2017 04:16:51 > abb3f6: INFO] Powershell execution start
[05/02/2017 04:17:58 > abb3f6: ERR ] 
[05/02/2017 04:17:58 > abb3f6: ERR ] Unhandled Exception: System.Management.Automation.CommandNotFoundException: The term 'Connect-SPOService' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
[05/02/2017 04:17:58 > abb3f6: ERR ]    at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
[05/02/2017 04:17:58 > abb3f6: ERR ]    at System.Management.Automation.RunspaceInvoke.Invoke(String script, IEnumerable input)

Thanks for your help

9 Replies

You shoudl try to set $env:PSModulePath it looks like your modules aren't being found. Did you publish the modules to your Azure environment?

I have just deployed the project using publish to azure and in package file i can see reference to dll's. do i need to explicitly publish the dll to azure. can you tell me how can we do that.

Thanks

Hi @KJS,

 

I'm having to make some assumptions. But if your module files are in Azure then you migth find that they aren't in the location where you expect them to be.

 

In general I first get the path where I'm running my scripts form:

 

 

 $path = Split-Path -parent $MyInvocation.MyCommand.Definition

Then I set my module path 

 

 

if ($env:PSModulePath -notlike "*$path\Modules\MyModules\Modules*")
{
      $env:PSModulePath += ";$path\Modules\MyModules\Modules"
}

you might find that when you build abnd publish your project the module files are found in (and therefore published to) the bin/debug folder.

 

 

 

 

 

Thanks for the reply 

 

I tried refrencing the path in the c# code but it did not worked

InitialSessionState initialSession = InitialSessionState.CreateDefault();
initialSession.ImportPSModule(new string[] { "D:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\Microsoft.Online.SharePoint.PowerShell" });

 

this is the path in azure web job where all dll's are and it also has the code dll 

D:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\

 

Can you please tell do you want me to add it before the script with the above path 

 

 $path = Split-Path -parent $MyInvocation.MyCommand.Definition
if ($env:PSModulePath -notlike "*$path\Modules\MyModules\Modules*")
{
      $env:PSModulePath += ";$path\Modules\MyModules\Modules"
}


const string connectScript = "Import-Module Microsoft.Online.SharePoint.PowerShell \r\n $AdminUrl = \"https://tenant-admin.sharepoint.com\" \r\n $UserName = \"user@tenant.onmicrosoft.com\" \r\n $Password = \"password\" \r\n $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force \r\n $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $SecurePassword \r\n Connect-SPOService -Url $AdminUrl -Credential $Credentials \r\n Get-SPOSite -Detailed -Limit All | select * ";


Thanks

You will need to replace \Modules\MyModules\Modules with the actual path where your modules live. Ensure that the fodler stucture is correct too. It is important that the Modules include a folder with the name of the actual module and then the module files need to exist in that folder.

 

 

I would set $path and $env:$PSModulePath inside your script (this is something that you can probably test by running it locally on your PC.)

 

Once the $env:PSModulePath is set correctly you will find that the modules are imported correctly ( assuming that the module files are located in the corrct place.

 

A few years ago I wrote some posts about PowerShell Modules:

 

https://veenstra.me.uk/2015/03/03/powershell-modules/

 

Thanks for the reply

 

I am not a very good at powershell all i am trying to do is call a powershell script from the C# code 

Connect-SPO commandlet is not my custom module or anything it is Sharepoint online management shell command which is just a package i installed on my machine to run it works fine on local.

 

I am passing the dll to azure

 

Path to code where all dll including the spo management shell dll is 

D:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\

 

exe file is also in the same folder where it is executing the code

 

can you please tell the exact code how to set that variable


if ($env:PSModulePath -notlike "*$pathD:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\*")
{
$env:PSModulePath += ";$path"
}

 

const string connectScript = " $path = Split-Path -parent $MyInvocation.MyCommand.Definition \r\n  Import-Module Microsoft.Online.SharePoint.PowerShell \r\n $AdminUrl = \"https://Newcrestmining-admin.sharepoint.com\" \r\n $UserName = \"kanwarjot.singh@newcrestmining.onmicrosoft.com\" \r\n $Password  = \"Crest99\" \r\n $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force \r\n $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $SecurePassword \r\n Connect-SPOService -Url $AdminUrl -Credential $Credentials \r\n Get-SPOSite -Detailed -Limit All | select * ";

Thanks,

KJ

Thanks for the reply

 

I am not a very good at powershell all i am trying to do is call a powershell script from the C# code 

Connect-SPO commandlet is not my custom module or anything it is Sharepoint online management shell command which is just a package i installed on my machine to run it works fine on local.

 

I am passing the dll to azure

 

Path to code where all dll including the spo management shell dll is 

D:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\

 

exe file is also in the same folder where it is executing the code

 

can you please tell the exact code how to set that variable

if ($env:PSModulePath -notlike "*$pathD:\\home\\site\\wwwroot\\app_data\\jobs\\triggered\\NMLSiteStorage\\*")
{
$env:PSModulePath += ";$path"
}

 

const string connectScript = " $path = Split-Path -parent $MyInvocation.MyCommand.Definition \r\n  Import-Module Microsoft.Online.SharePoint.PowerShell \r\n $AdminUrl = \"https://Newcrestmining-admin.sharepoint.com\" \r\n $UserName = \"kanwarjot.singh@newcrestmining.onmicrosoft.com\" \r\n $Password  = \"Crest99\" \r\n $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force \r\n $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $SecurePassword \r\n Connect-SPOService -Url $AdminUrl -Credential $Credentials \r\n Get-SPOSite -Detailed -Limit All | select * ";

Thanks,

KJ

The issue will be that the Sharepoint online management shell is not installed within your Azure context.

 

By default the module is installed in:

 

C:\Program Files\SharePoint Online Management Shell\

 

So you will need to copy the files in C:\Program Files\SharePoint Online Management Shell  (this is a folder  called Microsoft.Online.SharePoint.PowerShell) including the contents of the folder to Azure.

 

Then include the location where you put the folder in your $env:PSModulePath and you should be up and running.

 

Thanks i will try to include and push that folder to azure. and then refere the module.

 

Not sure if i can do it.

 

Thanks for the help