问题
I have one powershell script which has multiple function and one function is calling another function. I want to execute that function with some argument using node js. I am using node-powershell npm, but it executes only powershell command not a function. I have done this with C#, but in node js i am not able to do this.
C# code to run powershell function:
using (var runspace = RunspaceFactory.CreateRunspace())
{
try
{
log.Info(domain+"," + devicetype + "," + fullpath + "," + computername + "," + description );
var script = File.ReadAllText(HttpContext.Current.Server.MapPath(@"~\Scripts\ComputerOperation.ps1"));
runspace.Open();
var ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddScript(script);
ps.Invoke("Set-ExecutionPolicy Unrestricted");
ps.AddCommand("createComputer").AddParameters(
new Dictionary<string, string>
{
{ "domaincontroller" ,domain},
{"sitecode",sitecode },
{ "devicetype",devicetype},
{ "organizationUnit",fullpath},
{ "computername",computername},
{ "description",description},
{ "source",UserLoginController.version},
{ "ipAddress" , ipaddress},
{ "username",username}
});
foreach (PSObject result in ps.Invoke("Set-ExecutionPolicy Unrestricted"))
{
if (result != null)
{
log.Info("result=" + result.ToString());
return result.ToString();
}
}
}
catch (Exception ex)
{
log.Error(ex.Message);
return ex.Message;
}
}
Node JS Code to run powershell command:
let cmd = './Scripts/ComputerOperation.ps1';
return new Promise((resolve, reject) => {
ps.addCommand(cmd)
ps.addParameters([{ domainController: computer.domain },{ sitecode: computer.siteCode },{ organizationUnit: 'OU=Legacy,OU=ARBUE,OU=AMER' },{ computername: computer.computerName },{ description: computer.description },{ devicetype: computer.deviceType }])
ps.invoke()
.then(response => {
resolve(JSON.parse(JSON.stringify({ message: response })));
})
.catch(err => {
reject(err);
ps.dispose();
});
});
Powershell Script:
$Logfile = "C:\inetpub\wwwroot\UmgAcra\Scripts\log.log"
Function LogWrite{
Param ([string]$logstring)
try{
$timestamp = Get-Date
$logstring = $timestamp.ToString() +" - "+ $logstring
Add-content $Logfile -value $logstring
}
catch{
}
}
function getDirectoryEntryObject {
param([string]$path)
$Error.Clear();
try {
$directoryEntry = New-Object System.DirectoryServices.DirectoryEntry $path;
}
catch{
$er = $Error;
Logwrite("Error occured in $($MyInvocation.MyCommand.Name) $($Error)")
}
return $directoryEntry;
}
function createComputer {
param([string]$domainController,[string]$sitecode, [string]$organizationUnit, [string]$computername,[string]$description,[string]$devicetype,[string] $source ,[string] $ipAddress,[string] $username)
try{
LogWrite ("DomainController= "+$domainController+" OU= "+$organizationUnit+" computername= "+ $computername)
try{
$rootEntry = getDirectoryEntryObject -path "LDAP://$domainController"
$parentPath = $rootEntry.Path + "/" + $organizationUnit + "," + $rootEntry.Properties["distinguishedName"];
$objectPath=$rootEntry.Path + "/" +"OU="+$devicetype+","+$organizationUnit + "," + $rootEntry.Properties["distinguishedName"];
$parent = getDirectoryEntryObject -path $objectPath -credential $Cred;
if ($parent -eq $null -or $parent.Children -eq $null) {
#throw New-Object System.ArgumentException("$parentPath could not be found");
return "Path doesn't exist in AD. Please contact the support team for Organization Unit creation : "+" OU="+$devicetype+","+$organizationUnit
# please contact the support team for Organization Unit Creation
}
}
catch{
return " Error occured in createComputer An Active Directory Domain Controller for the domain ($domaincontroller) could not be contacted."
}
$adObject = $parent.Children.Add("CN=" + $computername, "computer");
if ($adObject -eq $null) {
throw New-Object System.ArgumentException("Unable to add new object (check AD permissions)");
}
$adObject.Properties["sAMAccountName"].Value = $computername.ToUpper() + "$";
$adObject.Properties["userAccountControl"].Value = 0x1020;
if($description -ne $null -and $description -ne "")
{
$adObject.Properties["description"].Value = $description;
}
if($sitecode -ne $null -and $sitecode -ne "")
{
$adObject.Properties["extensionAttribute3"].Value=$sitecode
}
$adObject.CommitChanges();
$result ="Computer "+$computername +" successfully created.";
return $result;
}
catch
{
$er = $Error;
Logwrite("Error occured in $($MyInvocation.MyCommand.Name) $($Error)");
return "Failed : " +$Error;
}
}
this script is not working and nothing is being returned from script but when i have updated same script by removing the function name 'createComputer' and also remove the function call 'LogWrite' and 'getDirectoryEntryObject' from the createComputer function then it is working fine.
My Updated Script:
param([string]$domainController,[string]$sitecode, [string]$organizationUnit, [string]$computername,[string]$description,[string]$devicetype)
try{
#LogWrite ("DomainController= "+$domainController+" OU= "+$organizationUnit+" computername= "+ $computername)
try{
$Logfile = "C:\Users\Asif\UMGv2\Node JS Backend\Scripts\log.log"
$timestamp = Get-Date -Format g
$logstring = "DomainController= "+$domainController+" SiteCode="+$sitecode+" OrganizationUnit= "+$organizationUnit+" computername= "+ $computername+" Description="+$description+" DeviceType="+$devicetype
$logstring = $timestamp.ToString() +" - "+ $logstring
Add-content $Logfile -value $logstring
}catch
{
}
try{
$organizationUnit = $organizationUnit.Replace(" ",",");
Add-content $Logfile -value $organizationUnit
$rootEntry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$domainController"
$parentPath = $rootEntry.Path + "/" + $organizationUnit + "," + $rootEntry.Properties["distinguishedName"];
$objectPath=$rootEntry.Path + "/" +"OU="+$devicetype+","+$organizationUnit + "," + $rootEntry.Properties["distinguishedName"];
$parent = New-Object System.DirectoryServices.DirectoryEntry $objectPath
if ($parent -eq $null -or $parent.Children -eq $null) {
#throw New-Object System.ArgumentException("$parentPath could not be found");
return "Error;Path doesn't exist in AD. Please contact the support team for Organization Unit creation : "+" OU="+$devicetype+","+$organizationUnit
# please contact the support team for Organization Unit Creation
}
}
catch{
return "Error;Error occured in createComputer An Active Directory Domain Controller for the domain ($domaincontroller) could not be contacted."
}
$adObject = $parent.Children.Add("CN=" + $computername, "computer");
if ($adObject -eq $null) {
throw New-Object System.ArgumentException("Error;Unable to add new object (check AD permissions)");
}
$adObject.Properties["sAMAccountName"].Value = $computername.ToUpper() + "$";
$adObject.Properties["userAccountControl"].Value = 0x1020;
if($description -ne $null -and $description -ne "" -and $description -ne 'none')
{
$adObject.Properties["description"].Value = $description;
}
if($sitecode -ne $null -and $sitecode -ne "")
{
$adObject.Properties["extensionAttribute3"].Value=$sitecode
}
$Error.Clear()
$adObject.CommitChanges();
return "Success;Computer "+$computername +" successfully created.";
}
catch
{
$er = $Error;
Add-content $Logfile -value "Error occured in $($MyInvocation.MyCommand.Name) $($Error)"
#Logwrite("Error occured in $($MyInvocation.MyCommand.Name) $($Error)");
return "Error;"+$Error;
}
I think, through node-powershell we can only execute powershell command and i want to call powershell function then how to do this using Node.js? Actually i am finding some alternative to call powershell function instead of powershell command through Node.js
回答1:
The problem is that your Node.js invocation doesn't dot-source the *.ps1
script file, which is necessary in order to call the createComputer
function defined therein.
Therefore, try the following:
// This command dot-sources the script.
let cmd = '. ./Scripts/ComputerOperation.ps1'
return new Promise((resolve, reject) => {
ps.addCommand(cmd)
// Now that the script is sourced, you can call the `createComputer` function.
ps.addCommand('createComputer')
ps.addParameters([{ domainController: computer.domain },{ sitecode: computer.siteCode },{ organizationUnit: 'OU=Legacy,OU=ARBUE,OU=AMER' },{ computername: computer.computerName },{ description: computer.description },{ devicetype: computer.deviceType }])
ps.invoke()
.then(response => {
resolve(JSON.parse(JSON.stringify({ message: response })))
// Be sure to call .dispose() after execution.
ps.dispose()
})
.catch(err => {
reject(err)
ps.dispose()
})
})
On a side note re the node-powershell package:
As of 8 Apr 2020, the sample commands in the documentation show incorrect use of the .addArgument
/ addParameter
/ addParameters
method calls - see this GitHub issue.
来源:https://stackoverflow.com/questions/61039229/how-to-execute-powershell-script-function-with-arguments-using-node-js