Call Powershell function from C# - c#

Hi to all I want to call in C# a powershell script. Inside ps1 file I have implemented a function.
Powershell script:
Add-Type -path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
Add-Type -path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll'
#$CourseName = Read-host "Enter site name"
CreateBlogSubsite($SiteName)
Function CreateBlogSubsite($SiteName)
{
$user = "johndoe#tenant.onmicrosoft.com";
$pass = "P3003ksi434!";
$secpw = $pass | ConvertTo-SecureString -AsPlainText -Force
$SiteURL = "https://tenant.sharepoint.com/sites/SalesSite/"
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL);
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user,$secpw);
$Context.Credentials = $Creds;
Try {
#Specify Subsite details
$WebCI = New-Object Microsoft.SharePoint.Client.WebCreationInformation
$WebCI.Title = $SiteName + " Blog" # sitename
$WebCI.WebTemplate = "Blog#0" #Blog Site #site template
$WebCI.Url = $SiteName + "_Blog"
$SubWeb = $Context.Web.Webs.Add($WebCI)
$Context.ExecuteQuery()
$URI = $SiteURL + $WebCI.Url
return $URI
#Write-host "Subsite Created Successfully! Url is: " + $SiteName + "1Blog" -ForegroundColor Green
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
}
Here is my console program, where I call PS script:
static void Main(string[] args)
{
// Execute powershell script
// Initialize PowerShell engine
var shell = PowerShell.Create();
//Add the script via a pre-made ps1 file
shell.Commands.AddScript(#"C:\\Users\\zeb\\source\\CreateCourseBlog.ps1");
shell.Commands.AddParameter("$SiteName", "Desti");
// Execute the script
var results = shell.Invoke(); // I want to get output of Poweshell function
Console.Write(results);
}
But it does not works :( . So, does not create subsite when I call script from c#

This should work:
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = rs;
ps.AddScript($#"C:\Users\zeb\source\CreateCourseBlog.ps1 -SiteName Desti");
ps.AddCommand("Out-String");
var psOutput = ps.Invoke();
foreach (var item in psOutput)
{
if (item == null) continue;
Console.WriteLine(item.BaseObject.ToString());
}
if (ps.Streams.Error.Count > 0)
Console.WriteLine($"Errors ({ps.Streams.Error.Count}):\n");
foreach (var err in ps.Streams.Error)
Console.WriteLine(" - " + err);
}
In addition to this code you should add next code to the top of your powershell script:
Param(
[string] $SiteName
)

Related

System.Automation.Runspaces Error in .NET Core project

I've tried to run the a piece of code in a Console Application - C# (.NET Framework 4.5 project) and it works. But when I tried to migrate it to ASP.NET Core 2.0, the code would return an error(as shown below).
using System.Management.Automation.Runspaces;
public void Powershell()
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("Import-Module AzureAD -Force;");
pipeline.Commands.AddScript("$password = ConvertTo-SecureString " + "\"Accenture01\"" + " -AsPlainText -Force");
pipeline.Commands.AddScript("$Cred = New-Object System.Management.Automation.PSCredential (" + "\"TestID01#eso.dev.accenture.com\"" + ", $password)");
pipeline.Commands.AddScript("Connect-AzureAD -Credential $Cred");
pipeline.Commands.AddScript("Get-AzureADApplication -Filter " + "\"DisplayName eq " + "\'TestApp\'" + "\"");
var result = pipeline.Invoke();
}
The error is
"'System.PlatformNotSupportedException: 'ReflectionOnly loading is
not supported on this platform.'"
Any ideas on this?
Use Powershell.Create() instead of Pipeline, Invoke the Import-Module before you continue, use Add-Command instead of AddScript
Try this: (after opening the runspace, e.g runspace.Open();)
using (var powershell = PowerShell.Create())
{
powershell.Runspace = runspace;
powershell.Commands.AddCommand("Import-Module").AddArgument("AzureAD");
powershell.Invoke();
powershell.Commands.Clear();
powershell.AddScript("$password = ConvertTo-SecureString " + "\"Accenture01\"" + " -AsPlainText -Force");
powershell.AddScript("$Cred = New-Object System.Management.Automation.PSCredential (" + "\"TestID01#eso.dev.accenture.com\"" + ", $password)");
powershell.AddScript("Connect-AzureAD -Credential $Cred");
powershell.AddScript("Get-AzureADApplication -Filter " + "\"DisplayName eq " + "\'TestApp\'" + "\"");
powershell.Invoke();
var results = powershell.Invoke();
}

Deploying Web Jobs Using ARM or the Powershell Script

I am trying to deploy Web job in to Azure using powershell script where we have our own deployment Framework, when i am deploying from my local machine it is deploying successfully only if i have the Admin or Co- Admin permissions if i have contributor Access script fails.Our deployment framework has only contributor permissions, Is there any way to deploy web job with the contributor permissions and I didn't found any ARM templates for Web Job deployment where i have solution file in local . Any suggestions please
Here is my script
`Add-AzureAccount (since web job doesn't have any RM commandlett i am using classic login where All our resource are in RM )
Select-AzureSubscription -SubscriptionName "*************"
$packageSource ="$Global:packageDir/../output\deletelogs\bin"
$destinationSource = "$env:TEMP\DeleteLogsWebjob.zip"
If(Test-path $destinationSource) {Remove-item $destinationSource}
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($packageSource, $destinationSource)
$webappname = AzCreateWebAppName "mywebapp$(Get-Random)"
$location = "EastUs" #GetCurrentRegion
$resourceGroupName= "*****" # AzGetResourceGroup
$webjobName = $webappname +"_deletelogsjob"
$jobCollecctionName = $webappname + $webjobName + "JobCollection"
#<### Defining Schedules
#$date = Get-Date
#$startDate = $date.ToString("MM-dd-yyy HH:mm tt")
#$endDate = $date.AddYears(1).ToString("MM-dd-yyy HH:mm tt")#>
# #Create an App Service plan in Free tier.
New-AzureRmAppServicePlan -Name $webappname -Location $location -ResourceGroupName $resourceGroupName -Tier Basic
## Create a web app.
$webapp = New-AzureRmWebApp -Name $webappname -Location $location -AppServicePlan $webappname -ResourceGroupName $resourceGroupName
###### Create WebJob
$job = New-AzureWebsiteJob -Name $webapp -JobName $webjobName -JobType Triggered -JobFile $destinationSource
$jobCollection = New-AzureRmSchedulerJobCollection -Location $location -JobCollectionName $jobCollecctionName -ResourceGroupName $resourceGroupName
$temp = "$env:TEMP\appsetting.xml"
$file = Get-AzureRMWebAppPublishingProfile -ResourceGroupName $resourceGroupName -Name $webappname -OutputFile $temp -Format WebDeploy
$webSitePassword = ([xml]$file).ChildNodes[0].ChildNodes[0].Attributes[5].Value
$webSiteUserName = ([xml]$file).ChildNodes[0].ChildNodes[0].Attributes[4].Value
$uri = "https://{0}:{1}#{2}.scm.azurewebsites.net/api/triggeredwebjobs/{3}/run" -f $webSiteUserName, $webSitePassword,$webappname, $webjobName
New-AzureRmSchedulerHttpJob -ResourceGroupName $resourceGroupName `
-JobCollectionName $jobCollection[0].JobCollectionName -JobName "deleteLogsScheduler" -Method POST `
-URI $uri -StartTime $startDate -Interval 2 -Frequency Minute `
-EndTime $endDate`
You could use example in this blog.
#Resource details :
$resourceGroupName = "<Resourcegroup name>";
$webAppName = "<WebApp name>";
$Apiversion = 2015-08-01
#Function to get Publishing credentials for the WebApp :
function Get-PublishingProfileCredentials($resourceGroupName, $webAppName){
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType
$resourceType -ResourceName $resourceName -Action list -ApiVersion $Apiversion -Force
return $publishingCredentials
}
#Pulling authorization access token :
function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName){
$publishingCredentials = Get-PublishingProfileCredentials $resourceGroupName $webAppName
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f
$publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}
$accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname
#Generating header to create and publish the Webjob :
$Header = #{
'Content-Disposition'='attachment; attachment; filename=Copy.zip'
'Authorization'=$accessToken
}
$apiUrl = "https://$webAppName.scm.azurewebsites.net/api/<Webjob-type>/<Webjob-name>"
$result = Invoke-RestMethod -Uri $apiUrl -Headers $Header -Method put -InFile "<Complete path of the file>\
<filename>.zip" -ContentType 'application/zip'
#NOTE: Update the above script with the parameters highlighted and run in order to push a new Webjob under the specified WebApp.
For Kudu authorization
$creds = Invoke-AzureRmResourceAction -ResourceGroupName YourResourceGroup -ResourceType Microsoft.Web/sites/config -ResourceName YourWebApp/publishingcredentials -Action list -ApiVersion 2015-08-01 -Force
$username = $creds.Properties.PublishingUserName
$password = $creds.Properties.PublishingPassword
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$apiBaseUrl = "https://$($website.Name).scm.azurewebsites.net/api"
$kuduVersion = Invoke-RestMethod -Uri "$apiBaseUrl/environment" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
This following lines of code is power shell script which allows you to deploy webjob in a web app . The parameters are passed through the settings file reference ...
#Requires -Version 3.0
Param(
[string] $settingsFileName = '\Settings\settings.json',
[boolean] $unitTestMode = $false
)
$Apiversion = "2015-08-01"
# Define FUNCTIONS
#Check if any requirement is missing
function Test-ParameterSet
{
param
(
[parameter(Mandatory = $true)][System.Object]$settings
)
# Loop through the $settings and check no missing setting
if ($null -eq $applicationFileJson.subscriptions) {throw "Missing subscriptions field in settings file"}
foreach ($subscription in $applicationFileJson.subscriptions)
{
if ($null -eq $subscription.subscriptionId) {throw "Missing subscription Id field in settings file"}
# Loop through the $settings and check no missing setting
foreach ($vault in $settings.WorkLoads)
{
if ($null -eq $vault.applicationName) {throw "Missing applicationNam in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.environmentName) {throw "Missing environmentName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.resourceGroupName) {throw "Missing resourceGroupName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webAppName) {throw "Missing webAppName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.Storagerg) {throw "Missing Storagerg in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webjobname) {throw "Missing webjobname in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webjobtype) {throw "Missing webjobtype in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.storageAccountName) {throw "Missing storageAccountName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.container_name) {throw "Missing container_name in settings file for $($subscription.subscriptionId)"}
If ($vault.webjobtype -eq "triggeredwebjobs")
{
if ($null -eq $vault.trigger_type) {throw "Missing trigger_type in settings file for $($subscription.subscriptionId)"}
}
}
If ($vault.webjobtype -eq "triggeredwebjobs" -and $vault.trigger_type -eq "scheduled")
{
if ($null -eq $vault.schedule) {throw "Missing schedule in settings file for $($subscription.subscriptionId)"}
If ($vault.webjobtype -eq "continuouswebjobs")
{
if ($null -eq $vault.continuous_type) {throw "Missing continuous_type in settings file for $($subscription.subscriptionId)"}
}
}
return $true
}
}
function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName)
{
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion $Apiversion -Force
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}
function Publish-webjob
{
[OutputType([String])]
param
(
[parameter(Mandatory = $true)][string]$resourceGroupName,
[parameter(Mandatory = $true)][string]$webAppName,
[parameter(Mandatory = $true)][string]$Storagerg,
[parameter(Mandatory = $true)][string]$webjobname,
[parameter(Mandatory = $true)][string]$webjobtype,
[parameter(Mandatory = $true)][string]$storageAccountName,
[parameter(Mandatory = $true)][string]$container_name,
[parameter(Mandatory = $true)][string]$settingsFileName,
[parameter(Mandatory = $true)][string]$i
)
#Check resource group exist
try {
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction Stop
}
catch {
$resourceGroup = $null
}
if ($null -eq $resourceGroup)
{
$message = "Resource group $resourceGroupName not found, deployment stop"
Write-Verbose $message
return $message
}
else
{
# Prepare deployment variables
Write-Verbose "ResourceGroup Found"
$SettingsJson = Get-JsonParameterSet -settingsFileName $settingsFileName
$trigger_type = "$($SettingsJson.WorkLoads[$i].trigger_type)"
Write-Verbose $trigger_type
$schedule = "$($SettingsJson.WorkLoads[$i].schedule)"
Write-Verbose $schedule
$continuous_type = "$($SettingsJson.WorkLoads[$i].continuous_type)"
Write-Verbose $continuous_type
}
# Unlock ResourceGroup
Unlock-ResourceGroup $resourceGroupName
write-verbose "ResourceGroup Unlocked"
$accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname
#Get storage account context and storage bolo
$sa= Get-AzureRmStorageAccount -ResourceGroupName $Storagerg -Name $storageAccountName
$ctx=$sa.Context
$blobs = Get-AzureStorageBlob -Container $container_name -Context $ctx
$webjobtype=$webjobtype+"webjobs"
$apiUrl = "https://$webAppName.scm.azurewebsites.net/api/$webjobtype/$webjobname"
#create a folder to save all the files of the container
$Location=$PSScriptRoot
New-Item -Path $Location -Name $webjobname -ItemType "directory" -Force
$folderPath = "$Location"+"\"+$webjobname
$localFile = $Location+"\"+$webjobname+"\"
#Generating header to create and publish the Webjob :
$Header = #{
"Content-Disposition"="attachment;filename=$($webAppName)"
"Authorization"=$accessToken
}
#Check if the storage container is empty
If($blobs.Count -eq 0)
{
Write-Error "The storage container is found empty"
}
#get files from container
foreach ($blob in $blobs)
{
$file=New-TemporaryFile
$file=Get-AzureStorageBlobContent -Container $container_name -Blob $blob.Name -Context $ctx -Destination $localFile -Force
$contents = Get-Content $localFile -Raw -ErrorAction:SilentlyContinue
$f=New-TemporaryFile
Add-Content $f $contents
}
If ($webjobtype -eq "triggeredwebjobs" -and $trigger_type -eq "scheduled")
{
$f = New-TemporaryFile
$r="{ ""schedule"" : "+""""+ $schedule+"""" + "}"
Add-Content $f $r
$destination=$Location+"\"+$webjobname+"\settings.job"
Move-Item -Path $f -Destination $destination
}
If ($webjobtype -eq "continuouswebjobs")
{
$f = New-TemporaryFile
If($continuous_type -eq "singleinstance")
{
$c="true"
}
If($continuous_type -eq "multipleinstance")
{
$c="false"
}
$r="{ ""is_singleton"" : " + $c + "}"
Add-Content $f $r
$destination=$Location+"\"+$webjobname+"\settings.job"
Move-Item -Path $f -Destination $destination
}
#Archive the files to a zip
$source = $localFile + "*"
$wz=$webjobname+".zip"
$destination = $Location+"\"+$webjobname+"\"+$wz
Compress-Archive -U -Path $source -DestinationPath $destination
#Deploying webjobs
$result = Invoke-RestMethod -Uri $apiUrl -Headers $Header -Method put -InFile $destination -ContentType 'application/zip' -ErrorAction Stop
Write-Host "Print result " -ForegroundColor Green
#delete the folder from local mahine
Remove-Item $folderPath -Force -Recurse -ErrorAction SilentlyContinue
# lock ResourceGroup
#Lock-ResourceGroup $resourceGroupName
write-verbose "ResourceGroup locked"
return $result
}
function Publish-Infrastructure
{
param(
[parameter(Mandatory = $true)][string]$settingsFileName
)
$settings = Get-JsonParameterSet -settingsFileName $settingsFileName
$deploymentIsSucceeded = $true
$workloadCount = $settings.WorkLoads.Count
Write-Verbose "workloadCounts: $workloadCount"
if($workloadCount -ge 1)
{
for($i = 0;$i -lt $workloadCount; $i++)
{
$applicationName = $settings.WorkLoads[$i].applicationName
Write-Verbose "application name: $applicationName"
$environmentName = $settings.WorkLoads[$i].environmentName
$applicationFile = "..\SettingsByWorkload\" + "nv_" + $applicationName + ".workload.json"
$applicationFile = Get-FileFullPath -fileName $applicationFile -rootPath $PSScriptRoot
$applicationFileJson = Get-JsonParameterSet -settingsFileName $applicationFile
Write-Verbose "application file json: $applicationName"
$null = Test-ParameterSet -settings $settings
$policyCount = $applicationFileJson.subscriptions.Count
Write-Verbose "$policyCount"
if($policyCount -ge 1)
{
for($j = 0;$j -lt $policyCount; $j++)
{
if($applicationFileJson.subscriptions[$j].environmentName -eq $environmentName)
{
$subscriptionId = $applicationFileJson.subscriptions[$j].subscriptionId
Write-Verbose "Environment Subscription: $($subscriptionId)"
Set-ContextIfNeeded -SubscriptionId $subscriptionId
foreach ($webjob in $settings.WorkLoads[$i])
{
$resourceGroupName = $webjob.resourceGroupName
$webAppName = $webjob.webAppName
$Storagerg = $webjob.Storagerg
$webjobname = $webjob.webjobname
$webjobtype = $webjob.webjobtype
$storageAccountName = $webjob.storageAccountName
$schedule = $webjob.schedule
$container_name = $webjob.container_name
$trigger_type = $webjob.trigger_type
Write-Verbose "Ready to start deployment on environment $EnvironmentName of a webjob in subscription $subscriptionId for resource group: $resourceGroupName"
$result = Publish-webjob ` -resourceGroupName $resourceGroupName `
-webAppName $webAppName `
-Storagerg $Storagerg `
-webjobname $webjobname `
-webjobtype $webjobtype `
-storageAccountName $storageAccountName `
-settingsFileName $settingsFileName `
-container_name $container_name `
-i $i
}
}
}
}
}
}
return $true
}
#START OF SCRIPT
if ($unitTestMode)
{
#do nothing
Write-Verbose 'Unit test mode, no deployment' -Verbose
}
else
{
#Log in Azure if not already done
try
{
$azureRmContext = Get-AzureRmContext -ErrorAction Stop
}
catch
{
$result = Add-AzureRmAccount
$azureRmContext = $result.Context
}
Write-Verbose "Subscription name $($azureRmContext.Subscription.Name)" -Verbose
$VerbosePreference = 'Continue'
# Get required templates and setting files. Throw if not found
$scriptsPath=$PSScriptRoot
$scriptsPath = Split-Path -Path $scriptsPath -Parent
$SettingsPath = Join-Path $scriptsPath $settingsFileName
$settingsFileName = $SettingsPath
Write-Verbose "Settings file name $($settingsFileName)" -Verbose
# Deploy infrastructure
return Publish-Infrastructure `
-settingsFileName $settingsFileName `
# END of script
}

Powershell resultset not being picked up in C#

When button1 is clicked, the below code is executed which will run a PowerShell script to get the current SQL Server Instances. However when this is run, the result set (results variable) has a count of 0 rows from the PowerShell output. When I run the same code in native PowerShell it displays 3 rows with the instance names.
Can anyone advise if I am missing something?
private void button1_Click(object sender, EventArgs e)
{
//If the logPath exists, delete the file
string logPath = "Output.Log";
if (File.Exists(logPath))
{
File.Delete(logPath);
}
string[] Servers = richTextBox1.Text.Split('\n');
//Pass each server name from the listview to the 'Server' variable
foreach (string Server in Servers)
{
//PowerShell Script
string PSScript = #"
param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server)
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force;
Import-Module SQLServer;
Try
{
Set-Location SQLServer:\\SQL\\$server -ErrorAction Stop;
Get-ChildItem | Select-Object -ExpandProperty Name;
}
Catch
{
echo 'No SQL Server Instances';
}
";
//Create PowerShell Instance
PowerShell psInstance = PowerShell.Create();
//Add PowerShell Script
psInstance.AddScript(PSScript);
//Pass the Server variable in to the $server parameter within the PS script
psInstance.AddParameter("server", Server);
//Execute Script
Collection<PSObject> results = new Collection<PSObject>();
try
{
results = psInstance.Invoke();
}
catch (Exception ex)
{
results.Add(new PSObject((Object)ex.Message));
}
//Loop through each of the results in the PowerShell window
foreach (PSObject result in results)
{
File.AppendAllText(logPath, result + Environment.NewLine);
// listBox1.Items.Add(result);
}
psInstance.Dispose();
}
}
To get an possible PowerShell error I would try sth. like this:
private void button1_Click(object sender, EventArgs e)
{
//If the logPath exists, delete the file
string logPath = "Output.Log";
if (File.Exists(logPath)) {
File.Delete(logPath);
}
string[] Servers = richTextBox1.Text.Split('\n');
//Pass each server name from the listview to the 'Server' variable
foreach (string Server in Servers) {
//PowerShell Script
string PSScript = #"
param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server)
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force;
Import-Module SQLServer;
Try
{
Set-Location SQLServer:\\SQL\\$server -ErrorAction Stop;
Get-ChildItem | Select-Object -ExpandProperty Name;
}
Catch
{
echo 'No SQL Server Instances';
}
";
using (PowerShell psInstance = PowerShell.Create()) {
psInstance.AddScript(PSScript);
psInstance.AddParameter("server", Server);
Collection<PSObject> results = psInstance.Invoke();
if (psInstance.Streams.Error.Count > 0) {
foreach (var errorRecord in psInstance.Streams.Error) {
MessageBox.Show(errorRecord.ToString());
}
}
foreach (PSObject result in results) {
File.AppendAllText(logPath, result + Environment.NewLine);
// listBox1.Items.Add(result);
}
}
}
}
The reason it isn't working is that psInstance.AddParameter only adds parameters to commands, it doesn't work with a script. You'll need to find another way of getting the $server parameter into the script. Try these two powershell examples to see what I mean. The first will output all processes (ignores the AddParameter) while the second only shows svchost processes.
1)
$ps = [system.management.automation.powershell]::create()
$ps.AddScript("get-process")
$ps.AddParameter("name","svchost")
$ps.invoke()
2)
$ps = [system.management.automation.powershell]::create()
$ps.AddCommand("get-process")
$ps.AddParameter("name","svchost")
$ps.invoke()
I managed to get round this issue by using the Win32_service instead of SQLPS.
Param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server)
$localInstances = #()
[array]$captions = GWMI Win32_Service -ComputerName $server | ?{$_.Name -match 'mssql *' -and $_.PathName -match 'sqlservr.exe'} | %{$_.Caption}
ForEach($caption in $captions)
{
if ($caption -eq 'MSSQLSERVER')
{
$localInstances += 'MSSQLSERVER'
}
else
{
$temp = $caption | %{$_.split(' ')[-1]} | %{$_.trimStart('(')} | %{$_.trimEnd(')')}
$localInstances += ""$server\$temp""
}
}
$localInstances;

PowerShell error : Cannot Invoke this function because the current host does not implement it

function LogMe() {
Param(
[parameter(Mandatory = $true, ValueFromPipeline = $true)]$logEntry,
[switch]$display,
[switch]$error,
[switch]$warning,
[switch]$progress
)
if ($error) {
$logEntry = "[ERROR] $logEntry"
Write-Host "$logEntry" -ForegroundColor Red
} elseif ($warning) {
Write-Warning "$logEntry"
$logEntry = "[WARNING] $logEntry"
} elseif ($progress) {
Write-Host "$logEntry" -ForegroundColor Green
} elseif ($display) {
Write-Host "$logEntry"
}
#$logEntry = ((Get-Date -uformat "%D %T") + " - " + $logEntry)
$logEntry | -force Out-File $logFile -Append
}
The above code spits out an error described in the title. I tried -force any other suggestions?
It's not C# per se but the error I'm getting is coming from C# when I run using pipeline.invoke.

How to call powershell script with configfile,parameters in c#

I am new powershell script in c#. I have a powershell script file ps.ps1 and powershell settingfile ConsoleSettings.psc1
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -psconsolefile "D:\e\ConsoleSettings.psc1" -noexit -command ". 'D:\e\ps.ps1'"
run it and get "
Get-RST -SearchRoot 'erd/user' -PasswordNeverExpires:$false
-PasswordNotChangedFor 60 -enabled
my function result correctly.
Now, i want to get this result in c# . My code is;
private void button1_Click(object sender, EventArgs e)
{
RunScript(LoadScript(#"d:\e\ps.ps1"));
}
private string RunScript(string scriptText)
{
PSConsoleLoadException x = null; ;
RunspaceConfiguration rsconfig = RunspaceConfiguration.Create(#"d:\e\ConsoleSettings.psc1", out x);
Runspace runspace = RunspaceFactory.CreateRunspace(rsconfig);
runspace.Open();
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
pipeline.Commands.Add("Get-RST -SearchRoot 'erd/user' -PasswordNeverExpires:$false -PasswordNotChangedFor 60 -enabled");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
private string LoadScript(string filename)
{
try
{
using (StreamReader sr = new StreamReader(filename))
{
StringBuilder fileContents = new StringBuilder();
string curLine;
while ((curLine = sr.ReadLine()) != null)
{
fileContents.Append(curLine + "\n");
}
return fileContents.ToString();
}
}
catch (Exception e)
{
string errorText = "The file could not be read:";
errorText += e.Message + "\n";
return errorText;
}
}
And then i have a error : the term "Get-RST -SearchRoot 'erd/user' -PasswordNeverExpires:$false -PasswordNotChangedFor 60 -enabled" 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.
How to solve this problem, or how to call powershell script with configfile, parameter like (Get-RST -SearchRoot 'erd/user' -PasswordNeverExpires:$false -PasswordNotChangedFor 60 -enabled) in c#
please help me...
You are adding your command line as a Command rather than a script. Commands are intended for things like cmdlets or functions without parameters. You will use the additional methods to add the parameters. A simple solution would be to just use AddScript again.
pipeline.AddScript("Get-RST -SearchRoot 'erd/user' -PasswordNeverExpires:$false -PasswordNotChangedFor 60 -enabled");

Categories