So I have a script to migrate users and I want to use that script in my application to make things faster and more simple. But there is some kind of problem, that I can't crack with current code.
Code runs to error in RunScript
when I start Invoking pipeline.
Note Script itself works without a problem, when I run it in PowerShell ISE as administrator
Here is my code
public class Migration
{
private static string scriptEmail = @"Add-PSSnapin Microsoft.SharePoint.Powershell
$url = '{0}'
$oldIdentity = '{1}'
$newIdentity = '{2}'
$email = '{3}'
$user = Get-SPUser -web $url -Identity $oldIdentity
Move-SPUser -IgnoreSID -Identity $user -NewAlias $newIdentity
$newUser=Get-SPUser -Identity '$newIdentity' -Web $url
Set-SPUser -Identity $newUser -Email $email
";
private static string scriptNoEmail = @"Add-PSSnapin Microsoft.SharePoint.Powershell
$url = '{0}'
$oldIdentity = '{1}'
$newIdentity = '{2}'
$user = Get-SPUser -web $url -Identity $oldIdentity
Move-SPUser -IgnoreSID -Identity $user -NewAlias $newIdentity
$newUser=Get-SPUser -Identity '$newIdentity' -Web $url
";
/// <summary>
/// Starts user migration proccess
/// </summary>
/// <param name="users">Users to migrate in order (first will be main user)</param>
/// <param name="email">User end email</param>
/// <param name="url">Site URL</param>
/// <returns>Did code excecute without errors</returns>
public static bool Start(List<WorkUser> users, string email, string url)
{
try
{
for (int i = users.Count; i > 1; i--)
{
string script = string.Empty;
if (email != string.Empty) // Kui on antud email ette (lisab etteantud emaili kasutajale)
{
script = string.Format(scriptEmail, url, users[i - 1].Account, users[i - 2].Account, email);
}
else // Kui emaili pole ette antud (kasutaja andmed jäävad samaks)
{
script = string.Format(scriptNoEmail, url, users[i - 1].Account, users[i - 2].Account);
}
Log.WriteToLog(string.Format("Running script | {0} |", script));
RunScript(script);
Log.WriteToLog(string.Format("Account \"{0}\" migrated to \"{1}\"", users[i - 1].Account, users[i - 2].Account));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
Log.WriteToLog(ex.ToString());
return false;
}
return true;
//string res = RunScript(script);
}
/// <summary>
/// Runs and excecutes PowerShell script
/// </summary>
/// <param name="scriptText">PowerShell script to excecute</param>
/// <returns>Result</returns>
private static string RunScript(string scriptText)
{
// create Powershell runspace
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
// open it
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
// 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 the results of the script that has
// now been converted to text
return stringBuilder.ToString();
}
}
}
Error, that I am getting is following:
System.Management.Automation.ParameterBindingValidationException: Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again. ---> System.Management.Automation.ValidationMetadataException: The argument is null. Provide a valid value for the argument, and then try running the command again.
at System.Management.Automation.ValidateNotNullAttribute.Validate(Object arguments, EngineIntrinsics engineIntrinsics)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
--- End of inner exception stack trace ---
at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
at UserMigrationTool.Code.Migration.RunScript(String scriptText) in c:\TauriVS\BCS.Sharepoint.Products.2013\UserMigrationTool\Code\Migration.cs:line 98
at UserMigrationTool.Code.Migration.Start(List`1 users, String email, String url) in c:\TauriVS\BCS.Sharepoint.Products.2013\UserMigrationTool\Code\Migration.cs:line 63