locked
Run PS script via ASP.NET page RRS feed

  • Question

  • Hi guys,

    I've just written an ASP.NET app that run a PS script in order to create new AD user accounts. The web server (IIS 7.0) is running on a Win2008R2 server (not domain controller) joined to the domain.

    The PS script is working fine locally on the server both via CLI and via web browser (through the ASP.NET app), but when I run it though a web browser on a remote client I get the following message: "Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.".

    The problem rises when the script calls the "get-aduser" command.

    The web app is using classic Windows authentication (AppPool) and, if I try to get the user who is running the script, I get my username as process owner, as expected.

    Why do I get different behaviours if I use the web app locally on the server or remotely?

    I hereby attach part of the ASP.NET and PS script code:

    PS Script code:

    # Define variables
    $path     = Split-Path -parent $MyInvocation.MyCommand.Definition
    $primaryGroup = "RADIUS Users"
    $i        = 0
    $userLocation = "OU=" + $devicetype + ",OU=MAC Addresses,OU=RADIUS Devices,OU=RADIUS,DC=rupar,DC=local"
    $userGroup = $devicetype
    $password = "mypassword"

    # FUNCTIONS

    Function createUsers
    {
    $Users = Import-Csv -Delimiter ";" -Path $file 
    $count = @(Get-Content $file).Length -1

    foreach ($User in $Users)  
    {
    $name = $User.name.replace(' ','')
    $name = $name.replace(':','')
    $name = $name.replace('-','')
    $name = $name.replace('.','')
    $firstName = $name.ToUpper()
    $lastName = $name.ToUpper()
    $sam = $name.ToLower()
    $displayName = $name.ToUpper()
    $upn = $sam + "@rupar.local"

    Try { $userExists = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)" }
    Catch { }

    If((!$userExists) -and ($sam -match "^[012345679abcdef]{12}$"))
    {
    $i++

    $setPass = ConvertTo-SecureString -AsPlainText $password -force
    New-ADUser -Name $displayName -GivenName $firstName -Surname $lastName -DisplayName $displayName -Description $description -EmailAddress $email -SamAccountName $sam -UserPrincipalName $upn -AccountPassword $setPass -Enabled $true -ChangePasswordAtLogon $false -PasswordNeverExpires $true -CannotChangePassword $true -Path $userLocation
    Add-ADPrincipalGroupMembership -Identity $sam -MemberOf $primaryGroup
    $GroupSid = (Get-ADGroup -Identity $primaryGroup -Properties PrimaryGroupID -ErrorAction Stop).SID
    $primaryGroupID = $groupSid.Value.Substring($groupSid.Value.LastIndexOf('-')+1)
    $dn  = (Get-ADUser $sam).DistinguishedName
    $ext = [ADSI]"LDAP://$dn"
    If ($_.ExtensionAttribute1 -ne "" -And $_.ExtensionAttribute1 -ne $Null)
    {
    $ext.Put("extensionAttribute1", $_.ExtensionAttribute1)
    $ext.SetInfo()
    }
    Set-ADObject -Identity $dn -replace @{PrimaryGroupID=$PrimaryGroupID}
    Remove-ADGroupMember -Identity "Domain Users" -Members $sam -Confirm:$false
    Try   { $groupExists = Get-ADGroup -Identity $userGroup }
    Catch { }
    If($groupExists)
    {
    Add-ADGroupMember -Identity $userGroup -Members $sam
    Add-ADGroupMember -Identity "MAC Addresses" -Members $sam
    $newPassword = ConvertTo-SecureString -AsPlainText $sam -Force
    Set-ADAccountPassword -Identity $sam -NewPassword $newPassword -Reset
    }
    }
    Else
    {
    Write-Output "SKIPPED - ALREADY EXISTS OR ERROR: $name" | Out-String
    Write-Output "----------------------------------------" | Out-String
    }
    }
    if ($i -lt $count)
    {
    Write-Output "The script has been executed with errors or users duplication occured! Created $i users out of $count. Check, please!" | Out-String
    }
    else
    {
    Write-Output "The script has been successfully executed! Created $i users out of $count." | Out-String
    }

    }


    # RUN SCRIPT
    createUsers
    #END

    ASP.NET C# code:

    protected void Submit_Button_Click(object sender, EventArgs e)
            {
                // Clean the Result TextBox
                ResultBox.Text = string.Empty;

                if (MacAddressList.Text != "")
                {
                    // Create the string for the full filename
                    string myfile = Server.MapPath("~/data") + "\\" + GetUniqueKey(20) + ".csv";
                    myfile.Replace("\\\\", "\\");

                    // Write the DeviceType textbox value into a file
                    Write_CSV_File(MacAddressList.Text, myfile);

                    // Import Active Directory module
                    InitialSessionState iss = InitialSessionState.CreateDefault();
                    iss.ImportPSModule(new string[] { "activedirectory" });

                    // Create a user's runspace
                    using (var psRunspace = RunspaceFactory.CreateRunspace(iss))
                    {
                        psRunspace.Open();

                        //Create a pipeline
                        using (Pipeline psPipeline = psRunspace.CreatePipeline())
                        {
                            // Create the command for the script to be launched
                            string myscript = @"E:\Scripts\webscript.ps1 -file '" + myfile + "' -description '" + Description.Text + "' -devicetype '" + DeviceType.SelectedValue + "' 2>&1";

                            // Add the PowerShell script to the pipeline object
                            psPipeline.Commands.AddScript(myscript);

                            // Execute the script
                            Collection<PSObject> results = psPipeline.Invoke();

                            // Display results, with BaseObject converted to string
                            if (results.Count > 0)
                            {
                                // We use a string builder to create our result text
                                var builder = new StringBuilder();

                                foreach (var psObject in results)
                                {
                                    // Convert the Base Object to a string and append it to the string builder.
                                    builder.Append(psObject.BaseObject.ToString() + "\r\n");
                                }

                                // Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
                                ResultBox.Text = Server.HtmlEncode(builder.ToString());
                            }
                            psPipeline.Commands.Clear();
                        }
                        psRunspace.Close();
                    }
                     
                    // Delete the temp file
                    Delete_CSV_File(myfile);
                }
                
            }

    Wednesday, October 11, 2017 9:41 AM

All replies

  • Second hop restriction.  You cannot pas credentials through to a third host under all normal conditions.  You must use a method that allows the credentials to be passed or you must use a remoting setup that can proxy the credentials.  The correct way to do this is via PWA.

    For custom web apps in ASP.Net you will need to post to the ASP.Net forum for assistance:

    http://forums.asp.net

    That is the official Microsoft ASP.Net forum.  They can point you at the documentation telling how to set up the web site to do this.  It is not a scriptin issue but is a web server issue.


    \_(ツ)_/

    Wednesday, October 11, 2017 9:51 AM
  • Thank you. I will post it to the right forum.

    :)

    Wednesday, October 11, 2017 10:07 AM
  • Hi,

    I'm checking how the issue is going, was your issue resolved?

    And if the replies as above are helpful, we would appreciate you to mark them as answers, and if you resolve it using your own solution, please share your experience and solution here. It will be greatly helpful to others who have the same question.

    Appreciate for your feedback.

    Best Regards,
    Albert Ling

    Please remember to mark the replies as an answers if they help and unmark them if they provide no help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    Friday, October 13, 2017 9:22 AM