I'm developing a Console application that must read from a PS1 file and execute the command from a Form. My runs very well when I have to call simple function PS1
I have this scrip1 that :
=======================================================================
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
#Function to copy user permissions
Function Copy-UserPermissions($SourceUserID, $TargetUserID, [Microsoft.SharePoint.SPSecurableObject]$Object)
{
#Determine the given Object type and Get URL of it
Switch($Object.GetType().FullName)
{
"Microsoft.SharePoint.SPWeb" { $ObjectType = "Site" ; $ObjectURL = $Object.URL; $web = $Object }
"Microsoft.SharePoint.SPListItem"
{
if($Object.Folder -ne $null)
{
$ObjectType = "Folder" ; $ObjectURL = "$($Object.Web.Url)/$($Object.Url)"; $web = $Object.Web
}
else
{
$ObjectType = "List Item"; $ObjectURL = "$($Object.Web.Url)/$($Object.Url)" ; $web = $Object.Web
}
}
#Microsoft.SharePoint.SPList, Microsoft.SharePoint.SPDocumentLibrary, Microsoft.SharePoint.SPPictureLibrary,etc
default { $ObjectType = "List/Library"; $ObjectURL = "$($Object.ParentWeb.Url)/$($Object.RootFolder.URL)"; $web = $Object.ParentWeb }
}
#Get Source and Target Users
$SourceUser = $Web.EnsureUser($SourceUserID)
$TargetUser = $Web.EnsureUser($TargetUserID)
#Get Permissions of the Source user on given object - Such as: Web, List, Folder, ListItem
$SourcePermissions = $Object.GetUserEffectivePermissionInfo($SourceUser)
#Iterate through each permission and get the details
foreach($SourceRoleAssignment in $SourcePermissions.RoleAssignments)
{
#Get all permission levels assigned to User account directly or via SharePOint Group
$SourceUserPermissions=@()
foreach ($SourceRoleDefinition in $SourceRoleAssignment.RoleDefinitionBindings)
{
#Exclude "Limited Accesses"
if($SourceRoleDefinition.Name -ne "Limited Access")
{
$SourceUserPermissions += $SourceRoleDefinition.Name
}
}
#Check Source Permissions granted directly or through SharePoint Group
if($SourceUserPermissions)
{
if($SourceRoleAssignment.Member -is [Microsoft.SharePoint.SPGroup])
{
$SourcePermissionType = "'Member of SharePoint Group - " + $SourceRoleAssignment.Member.Name +"'"
#Add Target User to the Source User's Group
#Get the Group
$Group = [Microsoft.SharePoint.SPGroup]$SourceRoleAssignment.Member
#Check if user is already member of the group - If not, Add to group
if( ($Group.Users | where {$_.UserLogin -eq $TargetUserID}) -eq $null )
{
#Add User to Group
$Group.AddUser($TargetUser)
#Write-Host Added to Group: $Group.Name
}
}
else
{
$SourcePermissionType = "Direct Permission"
#Add Each Direct permission (such as "Full Control", "Contribute") to Target User
foreach($NewRoleDefinition in $SourceUserPermissions)
{
#Role assignment is a linkage between User object and Role Definition
$NewRoleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($TargetUser)
$NewRoleAssignment.RoleDefinitionBindings.Add($web.RoleDefinitions[$NewRoleDefinition])
$object.RoleAssignments.Add($NewRoleAssignment)
$object.Update()
}
}
$SourceUserPermissions = $SourceUserPermissions -join ";"
Write-Host "***$($ObjectType) Permissions Copied: $($SourceUserPermissions) at $($ObjectURL) via $($SourcePermissionType)***"
}
}
}
Function Clone-SPUser($SourceUserID, $TargetUserID, $WebAppURL)
{
###Check Whether the Source Users is a Farm Administrator ###
Write-host "Scanning Farm Administrators Group..."
#Get the SharePoint Central Administration site
$AdminWebApp = Get-SPwebapplication -includecentraladministration | where {$_.IsAdministrationWebApplication}
$AdminSite = Get-SPWeb $AdminWebApp.Url
$AdminGroupName = $AdminSite.AssociatedOwnerGroup
$FarmAdminGroup = $AdminSite.SiteGroups[$AdminGroupName]
#enumerate in farm adminidtrators groups
foreach ($user in $FarmAdminGroup.users)
{
if($User.LoginName.Endswith($SourceUserID,1)) #1 to Ignore Case
{
#Add the target user to Farm Administrator Group
$FarmAdminGroup.AddUser($TargetUserID,"",$TargetUserID , "")
Write-Host "***Added to Farm Administrators Group!***"
}
}
### Check Web Application User Policies ###
Write-host "Scanning Web Application Policies..."
$WebApp = Get-SPWebApplication $WebAppURL
foreach ($Policy in $WebApp.Policies)
{
#Check if the search users is member of the group
if($Policy.UserName.EndsWith($SourceUserID,1))
{
#Write-Host $Policy.UserName
$PolicyRoles=@()
foreach($Role in $Policy.PolicyRoleBindings)
{
$PolicyRoles+= $Role
}
}
}
#Add Each Policy found
if($PolicyRoles)
{
$WebAppPolicy = $WebApp.Policies.Add($TargetUserID, $TargetUserID)
foreach($Policy in $PolicyRoles)
{
$WebAppPolicy.PolicyRoleBindings.Add($Policy)
}
$WebApp.Update()
Write-host "***Added to Web application Policies!***"
}
### Drill down to Site Collections, Webs, Lists & Libraries, Folders and List items ###
#Get all Site collections of given web app
$SiteCollections = Get-SPSite -WebApplication $WebAppURL -Limit All
#Convert UserID Into Claims format - If WebApp is claims based! Domain\User to i:0#.w|Domain\User
if( (Get-SPWebApplication $WebAppURL).UseClaimsAuthentication)
{
$SourceUserID = (New-SPClaimsPrincipal -identity $SourceUserID -identitytype 1).ToEncodedString()
$TargetUserID = (New-SPClaimsPrincipal -identity $TargetUserID -identitytype 1).ToEncodedString()
}
#Loop through all site collections
foreach($Site in $SiteCollections)
{
#Prepare the Target user
$TargetUser = $Site.RootWeb.EnsureUser($TargetUserID)
Write-host "Scanning Site Collection Administrators Group for:" $site.Url
###Check Whether the User is a Site Collection Administrator
foreach($SiteCollAdmin in $Site.RootWeb.SiteAdministrators)
{
if($SiteCollAdmin.LoginName.EndsWith($SourceUserID,1))
{
#Make the user as Site collection Admin
$TargetUser.IsSiteAdmin = $true
$TargetUser.Update()
Write-host "***Added to Site Collection Admin Group***"
}
}
#Get all webs
$WebsCollection = $Site.AllWebs
#Loop throuh each Site (web)
foreach($Web in $WebsCollection)
{
if($Web.HasUniqueRoleAssignments -eq $True)
{
Write-host "Scanning Site:" $Web.Url
#Call the function to Copy Permissions to TargetUser
Copy-UserPermissions $SourceUserID $TargetUserID $Web
}
#Check Lists with Unique Permissions
Write-host "Scanning Lists on $($web.url)..."
foreach($List in $web.Lists)
{
if($List.HasUniqueRoleAssignments -eq $True -and ($List.Hidden -eq $false))
{
#Call the function to Copy Permissions to TargetUser
Copy-UserPermissions $SourceUserID $TargetUserID $List
}
#Check Folders with Unique Permissions
$UniqueFolders = $List.Folders | where { $_.HasUniqueRoleAssignments -eq $True }
#Get Folder permissions
foreach($folder in $UniqueFolders)
{
#Call the function to Copy Permissions to TargetUser
Copy-UserPermissions $SourceUserID $TargetUserID $folder
}
#Check List Items with Unique Permissions
$UniqueItems = $List.Items | where { $_.HasUniqueRoleAssignments -eq $True }
#Get Item level permissions
foreach($item in $UniqueItems)
{
#Call the function to Copy Permissions to TargetUser
Copy-UserPermissions $SourceUserID $TargetUserID $Item
}
}
}
}
Write-Host "Permission are copied successfully!"
}
#Define variables for processing
$WebAppURL = "http://sp2010devid/sites/EsercioWeekend/"
#Provide input for source and Target user Ids
$SourceUser ="virtualsp\admnistrator"
$TargetUser ="virtualsp\b.ferreirarocha"
#Call the function to clone user access rights
Clone-SPUser $SourceUser $TargetUser $WebAppURL
==========================================================================
And the most important part of my C# Code that runs the script:
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace HowToRunPowerShell
{
public partial class FormPowerShellSample : Form
{
// Represents the kind of drag drop formats we want to receive
private const string dragDropFormat = "FileDrop";
public FormPowerShellSample()
{
InitializeComponent();
}
private void buttonRunScript_Click(object sender, EventArgs e)
{
try
{
textBoxOutput.Clear();
textBoxOutput.Text = RunScript(textBoxScript.Text);
}
catch (Exception error)
{
textBoxOutput.Text += String.Format("\r\nError in script : {0}\r\n", error.Message);
}
}
/// <summary>
/// Runs the given powershell script and returns the script output.
/// </summary>
/// <param name="scriptText">the powershell script text to run</param>
/// <returns>output of the script</returns>
private string RunScript(string scriptText)
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
PSSnapInException snapInError;
runspace.RunspaceConfiguration.AddPSSnapIn("Microsoft.SharePoint.PowerShell", out snapInError);
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
// add an extra command to transform the script output objects into nicely formatted strings
// remove this line to get the actual objects that the script returns. For example, the script
// "Get-Process" returns a collection of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
Collection<PSObject> results = pipeline.Invoke();
// close the runspace
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
#region Drag-drop handling events
private void FormPowerShellSample_DragDrop(object sender, DragEventArgs e)
{
// is it the correct type of data?
if (e.Data.GetDataPresent(dragDropFormat))
{
// dragging files onto the window yields an array of pathnames
string[] files = (string[])e.Data.GetData(dragDropFormat);
if (files.Length > 0)
{
// just read the first file
using (StreamReader sr = new StreamReader(files[0]))
{
// and plunk the contents in the textbox
textBoxScript.Text = sr.ReadToEnd();
}
}
}
}
private void FormPowerShellSample_DragEnter(object sender, DragEventArgs e)
{
// only accept the dropped data if it has the correct format
e.Effect = e.Data.GetDataPresent(dragDropFormat) ? DragDropEffects.Link : DragDropEffects.None;
}
#endregion
}
}
but when I try to run the script it return me the the following exception :
“Cannot Invoke this function because the current host does not implement it”
I found this post link and it Seems it Someone has found the same isseus and solve it with this procedure but i'm completely ignorant on PowerSehll.