How to reference PowerShell Module within ASP.NET Site - asp.net

I'm trying to figure out how to use the Microsoft Online Services Migration Toolkit PowerShell Commands from within an ASP.NET website (using vb.NET).
I've started off using a guide on how to use PowerShell in ASP.NET - from here: http://devinfra-us.blogspot.com/2011/02/using-powershell-20-from-aspnet-part-1.html
I'm trying to work out how to implement the Online Services Migration Toolkit PowerShell cmdlets.
Here is a snippet from my code-behind:
Sub GetUsers()
Dim iss As InitialSessionState = InitialSessionState.CreateDefault()
iss.ImportPSModule(New String() {"MSOnline"})
Using myRunSpace As Runspace = RunspaceFactory.CreateRunspace(iss)
myRunSpace.Open()
' Execute the Get-CsTrustedApplication cmdlet.
Using powershell As System.Management.Automation.PowerShell = System.Management.Automation.PowerShell.Create()
powershell.Runspace = myRunSpace
Dim connect As New Command("Get-MSOnlineUser -Enabled")
Dim secureString As New System.Security.SecureString()
Dim myPassword As String = "ThePassword"
For Each c As Char In myPassword
secureString.AppendChar(c)
Next
connect.Parameters.Add("Credential", New PSCredential("admin#thedomain.apac.microsoftonline.com", secureString))
powershell.Commands.AddCommand(connect)
Dim results As Collection(Of PSObject) = Nothing
Dim errors As Collection(Of ErrorRecord) = Nothing
results = powershell.Invoke()
errors = powershell.Streams.[Error].ReadAll()
For Each obj As PSObject In results
Response.Write(obj.Properties("Identity").Value.ToString())
Next
End Using
End Using
End Sub
When I try to run the code via the page, I'm getting the following error
The term 'Get-MSOnlineUser -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.
So I'm guessing I haven't worked out how to import the Online Services Migration Toolkit PowerShell CmdLets. I'm also not exactly sure if the line:
iss.ImportPSModule(New String() {"MSOnline"})
Is exactly correct. Is there a way I can verify the Module name?
I'm also unsure of where and how to reference the .dll files. At the moment I have copied them to my bin folder but I can't add them as references, so how does the ImportPSModule statement know where to find them? Especially when the website is published to the final production server.
One other question, should I be using the x86 or x64 cmdlets? I'm developing on Win7 x64, but not sure if the website builds as x86 or x64? Do I need to find out what architecture the server is?

"Get-MSOnlineUser -Enabled" is not a command; "Get-MSOnlineUser" is. I'm a bit confused how you got it correct further down the script with connect.Parameters.Add("Credential", ...) but didn't do the same thing for -Enabled.
Use connect.AddArgument("Enabled") or connect.Parameters.Add("Enabled", true) and you should be good to go.

Related

Silk Test Visual Test Pressed Enter Key

Let's say there's only one textbox on a page (no confirm button). I have inputted the text. How do I press enter? (in mobile, I can press the "enter" key in the keyboard, but there's no keyboard in visual test).
Can anyone please help me?
EDIT
So in the end I used .NET Script. But I can't integrate the script to Visual Test (the app reinstall itself from the beginning). It works if the scenario fully uses .NET Script, but then I need to change all the Visual Test to .NET Script (I need to make it all in Visual Test or .NET Script).
Does anybody know how to integrate this one function in .NET to Visual Test?
Here's my .NET Script:
Imports SilkTest.Ntf.Mobile
Public Module Main
Dim _desktop As Desktop = Agent.Desktop
Public Sub Main()
Dim map As IDictionary(Of String, Object) = New Dictionary(Of String, Object)()
map.Add("action", "Done")
_desktop.MobileDevice("Device").Invoke("executeScript", "mobile: performEditorAction", New Object() {map})
End Sub
End Module
====== the script's 'till here (I can't insert it into the code brackets) ======
Add a new command that does TypeKeys with an
I found the answer! So in properties pane in the .NET Script click the device name under Application Configurations and add ";noReset=true" in Connection String. Then, uncheck "Execute Base State".
With that, Silk Test will execute the inserted .NET Script in visual test without reinstalling the app.

Entity Framework migration: access sql file within ASP.NET

I have a ASP.NET Web API project. I'm using Entity Framework Migrations. Currently, I have a custom script that is to be executed during a migration. I'm using the SqlFile method for this:
SqlFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Migrations/Scripts/MyCustomScript.sql"));
This works fine in the integration tests, IF I set the "Copy to Output Directory" of the script to "Copy always".
However, when running the website, the script is copied to <websiteroot>\bin\Migrations\MyCustomScript.sql, while AppDomain.CurrentDomain.BaseDirectory points to the websiteroot. Therefore, an error is thrown stating that the script cannot be found: it resides in the bin folder, not in the root.
How can I load the script so that things work both in the tests and in the actual website?
I would include the script in you dll and than load the script from the dll directly. Than you do not need any if statements and you always know you have the correct scripts included. Set the build action to Embedded resource. Then you can get the script like:
Assembly assembly = Assembly.LoadFile(dll);
using (Stream stream = assembly.GetManifestResourceStream(resourcepath))
using (StreamReader reader = new StreamReader(stream))
{
string script = reader.ReadToEnd();
I would fix it this way (it's not the best way, but it's a way)
string sqlfilepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Migrations/Scripts/MyCustomScript.sql");
if (!File.Exists(sqlfilepath))
sqlfilepath = "your other path where it might exist";

System.Management.dll not recognised .Net 4.6

I am having a really wired issue where I have created a new ASP.Net 4.6 web application (Visual Studio 2015 Community Edition) and everything works fine.
The app will compile without any issues at all but as soon as I try to run the app on the development machine (Windows 10 Enterprise) I get the following error every time and I cannot figure out why?
BC30002: Type 'ConnectionOptions' is not defined.
The code I am using is as follows:
Dim Options As New ConnectionOptions()
Options.Username = HttpContext.Current.Application("WMIUser")
Options.Password = HttpContext.Current.Application("WMIPsssword")
Dim scope As New ManagementScope("\\" & server_name & "\root\cimv2", Options)
scope.Connect()
Dim objectQuery As New ObjectQuery("SELECT FreeSpace FROM Win32_LogicalDisk where DeviceID=""" + deviceId + ":""")
Dim objectSearcher As New ManagementObjectSearcher(scope, objectQuery)
Dim objectCollection As ManagementObjectCollection = objectSearcher.[Get]()
For Each m As ManagementObject In objectCollection
Dim FreeSpace As Double = Convert.ToDouble(m("FreeSpace"))
Next
I have a reference to the System.Management DLL in the references for the application and I have an Imports declaration for it also.
Has anyone come across this before? My searching all leads back to the DLL not being referenced in the application but I have added and removed and re-added without any change.
Please help this is driving me nuts :-(
OK so this is a funny one, posting up just in case someone else comes across the issue.
The way I resolved this problem on the development machine was under References for the project, you have the option to copy local, set this to true and rebuilt the application, ran it and hey presto it all worked.
I can only assume that this could be a permissions thing but this works for the moment anyway.
Hope this helps someone in the future.

EF 4.1 Code First Initialization - Alternative

I am building a web application using the entity framework and the code first approach and I really like it so far except one thing. The initialization process and seeding data is crap.
I have set it up as recommended with ASP.NET MVC with the setinitialiser being called in app start and a custom initialization class to add data but it always seems to fail silently and never work. (The database creation works just the data init fails)
Can anyone provide recommended paractice for this or a way to run an sql script from a file.
The given method for adding data, especially for a demo site seems cumbersome and I would prefer the ability to just run a database script directly from a file that is run once as part of an install process rather than depending on a process that fails without any indication that something has gone wrong.
EDIT
I have noticed it throwing exceptions ( idiotic datetime -> datetime2 conversion errors that should be handled by the entity framework.)
But part of the problem may be that my version of express 2010 is not breaking on errors it seems to be very buggy when debugging.
But the issue still stands. I find it a cumbersome and buggy way of essentially running sql scripts on the database. And don't want to end up with a huge set of methods and classes just to setup a demo site when someone installs my web application in IIS.
If you want to run SQL scripts from your initializer I would recommend adding
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
string scriptDirectory = HttpContext.Current.Server.MapPath("~/SqlScripts");
string sqlConnectionString = context.Database.Connection.ConnectionString;
DirectoryInfo di = new DirectoryInfo(scriptDirectory);
FileInfo[] rgFiles = di.GetFiles("*.sql");
foreach (FileInfo fi in rgFiles)
{
FileInfo fileInfo = new FileInfo(fi.FullName);
using (TextReader reader = new StreamReader(fi.FullName))
{
using (SqlConnection connection = new SqlConnection(context.Database.Connection.ConnectionString))
{
Server server = new Server(new ServerConnection(connection));
server.ConnectionContext.ExecuteNonQuery(reader.ReadToEnd());
}
reader.Close();
reader.Dispose();
}
}
The reason for using the SqlServer Management Objects is that you can use "GO" in your scripts. it then becomes incredibly easy to script from SSMS and paste the scripts into your SqlScripts directory.
You can find the SMO Libraries at:
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfo.dll
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.Sdk.Sfc.dll
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Smo.dll
and if you need help scripting your data
SP_Generate_Inserts
Until you will show reproducible code snippet where initialization fails without throwing an exception I hardly believe that this happens.
You can always execute any SQL script by falling back to classic ADO.NET with SqlConnection and SqlCommand. Just open the file, load commands into string and execute them with SqlCommand or Database.ExecuteSqlCommand.

First time installation / deployment on clients machine

We have a silverlight ASP .NET web application which needs to be deployed on client's server along with Sql Server database. Once they deploy on their server, many workstation can access it and run silverlight client.
I was thinking to create a small deployment project, add necessary script files to the resources, and create an msi Once after installation is completed, we can execute the sql scripts to add database and its tables. I am not sure if this is feasible, is there a better way of doing it? Also, if there are any future updates to the app / db, how can it be done on the server (silent update/install)?
Any links / steps / procedure is highly appreciated.
Thanks!
You can create the scripts using the MSI, and then you should be able to run them as part of the installation using sqlcmd or osql command line utility, you'll obviously need to let the user capture server name, db name and credentials as part of the install.
With updates to the db schema, you can do it through code in your application, which means you'll need to maintain a database version somewhere for the app to know when to run the script, or just script the relevant alter statements, and run it on the server as part of deployment, once again using one of the command line utilities.
Thanks for the reply Baldy. This is exactly what I thought and did a small test. I have a simple ASP .NET web application with one label, one class library project which has an overrides method Install (creates a batch file and executes it), wand a WebSetup project which actually installs and during installation it will execute the Install method from class library project. Here's the code -
1) ClassLibrary Project - MyCustomAction
<RunInstaller(True)> _
Public Class SetupAction
Inherits Installer
Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)
MyBase.Install(stateSaver)
Try
My.Computer.FileSystem.WriteAllText("E:\SetupTest.txt", Environment.NewLine + "File created from MyCustomAction project", True)
'Shell("SQLCMD -S Dev1 -d Prac -i ""E:\Copy of CreateTable1.sql""", AppWinStyle.MinimizedFocus, True, 5000)
File.WriteAllText("E:\Test.bat", "SQLCMD -S Dev1 -d Prac -i ""E:\CreateTable1.sql""")
Process.Start("E:\Test.bat")
Catch ex As Exception
My.Computer.FileSystem.WriteAllText("E:\ErrorLog.txt", Environment.NewLine + "Exception: " + ex.Message, True)
Finally
End Try
End Sub
End Class
2) ASP .NET Project - MyApplication
Partial Public Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Label1.Text = "Current Time: " + Now.ToString
End Sub
End Class
3) WebSetup Project - MyApplicationSetup
I have added the project output from the above projects to it
I have added a new "Tnstall" CustomAction referencing it to the output of MyCustomAction class library project
When I build the msi installer and install the Web Setup application it intalls (copies the output files), and also creates SetupTest.txt, Test.bat files but it neither executes the Shell command line statement nor Process.Start() successfully.
Once the bat file is created, if I manually double click it does execute the sql Script file.
As a side note, if I run CustomAction code in a separate Windows App, it executes perfectly fine. So, looks like while installation, its not able to execute the command line commands (though I do see cmd.exe / SQLCMD.exe in the task manager). I am not sure if this would be a permission issue, but I am in the admin group and have necessary permissions.
It may not be appropriate to write these comments in "My Answer" section, but wanted to give a detailed explanation of the situation. I am really stuck with this and would be very helpful if anyone can throw pointers on improving / alternate methods. Thanks in advance and really appreciate the help.

Resources