"Run time exception AADSTS50079: Due to a configuration change made by your administrator, or because you moved to a new location, you must enroll in multi-factor authentication"
static void Main(string[] args)
{
var builder = new
KustoConnectionStringBuilder("help.kusto.windows.net/Samples")
{
FederatedSecurity = true,
UserID = "***#microsoft.com",
Password = "****",
EnforceMfa = true
};
var client =
Kusto.Data.Net.Client.KustoClientFactory.CreateCslQueryProvider(builder);
var reader = client.ExecuteQuery("StormEvents | count");
}
If you are microsoft FTE and try to query kusto on a dotNet Core Console Application, I suggest you to use a dotNet Framework Console Application.
use
var client = Kusto.Data.Net.Client.KustoClientFactory.CreateCslQueryProvider("https://help.kusto.windows.net/Samples;Fed=true");
var reader = client.ExecuteQuery("MyTable | count");
// Read the first row from reader -- it's 0'th column is the count of records in MyTable
// Don't forget to dispose of reader when done.
see https://learn.microsoft.com/en-us/azure/kusto/api/netfx/about-kusto-data
Then it will pop up a window to use VSTS as a multi-factor authentication.
It seems that VSTS authentication not support dotNet Core.
Related
I'm creating a website and in it I'm giving a link where the user enters his/her Azure VM username and password and then I'm gonna go ahead and restart the machine IIS server.
So I'm writing a .NET Code for implementing the same but no luck yet. I'm not able to restart the IIS server for the remote machines, I have even looked for an alternative approach to achieve the same using Powershell but unable to do so.
I tried remotely restarting the IIS server using WMI and also created code for calling Powershell in .Net Core but I'm not able to achieve the same.
Can someone please help me with how to restart the IIS server remotely using C# code or .NET Core code?
As for this...
Share me the link wherein there is a PowerShell script that restarts
IIS on a remote server using the system credentials.
... a quick search using 'Restart IIS on remote machine'
... will give a list of articles in the topic, some from right here on StackOverflow, since this is not the first time this has been asked. So, your question can be considered a potential duplicate of the below.
Example(s):
about_Remote - PowerShell | Microsoft Docs
Restart IIS on remote machine
Some of the answers, not using PowerShell to do this from the above are:
# Simplest will be
iisreset <servername>
# Run command prompt as admin and execute the command.
# Example : If server name is SRVAPP then command will be iisreset SRVAPP
# You could use sc
sc \\RemoteServer stop iisadmin
sc \\RemoteServer start w3svc
# or SysInternals' psexec. The PsTools suite is useful for these scenarios.
psexec \\RemoteServer iisreset
PowerShell Remoting requires you to be in the local admin group on the target host. You cannot run PowerShell code as SYSTEM unless you are running a scheduled task, even then it is the scheduled task running as whatever credential it was set for and running any script in that task. To run PowerShell code as another user, you must know the username and password.
You can use PowerShell to set up a scheduled task to run. Just search for 'PowerShell scheduled task' for details.
I tried the below codes for restarting IIS remotely but it didn't work.
Method 1:
using System.Diagnostics;
using System.Management;
using System.IO;
using System.Security;
Process myProcess = new Process();
ProcessStartInfo remoteAdmin =
new ProcessStartInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "iisreset.exe"));
remoteAdmin.Arguments = "/restart";
myProcess.StartInfo.Verb = "runas";
var s = new SecureString();
//s.AppendChar('g');
Console.WriteLine("Enter username:");
string userName = Console.ReadLine();
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Enter password:");
string password = Console.ReadLine();
Console.WriteLine(Environment.NewLine);
var securePasswordString = new SecureString();
// Use ToCharArray to convert string to array.
char[] array = password.ToCharArray();
// Loop through array.
for (int i = 0; i < array.Length; i++)
{
// Get character from the array.
securePasswordString.AppendChar(array[i]);
}
remoteAdmin.UserName = userName;
remoteAdmin.Password = securePasswordString;
remoteAdmin.Domain = "localhost";
myProcess.StartInfo = remoteAdmin;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.Start(); //---ERROR HERE
if (!myProcess.Start())
{
// That didn't work
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Process did not start!!!");
}
myProcess.WaitForExit();
var processExitCode = myProcess.ExitCode;
if (processExitCode == 0)
{
Console.WriteLine("The operation completed successfully.");
}
if (processExitCode != 0)
{
// That didn't work
if (processExitCode == 5)
{
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Access Denied");
}
}
Console.ReadKey();
Method 2:
ConnectionOptions conn = new ConnectionOptions();
conn.Impersonation = ImpersonationLevel.Impersonate;
conn.Username = #"Username";
conn.Password = "";
//ManagementScope theScope = new ManagementScope("\\\\" + txtServerName.Text + "\\root\\cimv2", conn);
theScope.Connect(); //---ERROR HERE
I tried the below code to run powershell script from C# code but I need the script which takes remote server admin credentials and restart the IIS.
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
static void RunPsScriptMethod2()
{
StringBuilder sb = new StringBuilder();
PowerShell psExec = PowerShell.Create();
psExec.AddCommand(#"C:\Users\d92495j\Desktop\test.ps1");
psExec.AddArgument(DateTime.Now);
Collection<PSObject> results;
Collection<ErrorRecord> errors;
results = psExec.Invoke();
errors = psExec.Streams.Error.ReadAll();
if (errors.Count > 0)
{
foreach (ErrorRecord error in errors)
{
sb.AppendLine(error.ToString());
}
}
else
{
foreach (PSObject result in results)
{
sb.AppendLine(result.ToString());
}
}
Console.WriteLine(sb.ToString());
}
I want to authenticate to MongoDB with C# not through passing the Connection String/Credentials on the MongoClient() instance. It's like we do it on MongoDB Shell, We call monog -> db.auth(<username>,<password>) it means Connect to database first and authenticate after that.
Write C# Code
This is my code:
var mongoClient = new MongoClient();
var testDB = mongoClient.GetDatabase("test");
string username = txtUserName.Text;
string password = txtPassword.Password;
// Check password
var cmd = new BsonDocument("authenticate", new BsonDocument
{
{"username",username },
{"password",password }
});
var queryResult = testDB.RunCommand<BsonDocument>(cmd);
My Code connect to MongoDB and call the authenticate Database Command (described Here. It's not the db.auth() Shell method)to login with it
Run MongoDB with --auth option.
Run my Code.
After step 3, I encountered this problem. My code say
Additional information: Command authenticate failed: field missing/wrong type in received authenticate command.
I have read MongoDB documents (Also the link I added above) I can't find What I was missing.
I think you can use a JsonCommand to call eval function to execute db.auth function like this - not tested -:
var command = new JsonCommand<BsonDocument>(#"{ eval: ""db.auth(\""username\"", \""password\"");"" }");
var result = db.RunCommand(command);
I'm trying to run a query on LDAP, but I get exception UnauthorizedAccessException # new PrincipalSearcher(qbeUser). (see code below)
I don't understand why the application doesn't have access to run this query as when I run
ldapsearch command line tool it works fine.
using(PrincipalContext ctx = new PrincipalContext(ContextType.Machine, "machineName"))
{
using(UserPrincipal qbeUser = new UserPrincipal(ctx))
{
using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
{
foreach (var found in srch.FindAll())
{
var user = (UserPrincipal)found;
Console.WriteLine(user.GivenName + " " + user.Surname + " " + user.EmailAddress);
}
}
}
}
Here is an IBM technote on how to collect debug data for LDAP on the Domino server side. I would suggest using the LDAPDEBUG=7 setting right from the get-go, and comparing the console log output on the server for your ldapsearch query and your program's query.
What you probably need to pay attention to is the authentication during the bind operation. You haven't mentioned whether you passed any authentication info in the ldapsearch command line (-D and -w arguments), and you haven't said anything about SSO -- and I'm not even sure if Domino LDAP participates in any SSO. The data logged on the server should help clarify what (if any) identity your query is using for binding. Normal settings on the Domino Directory would protect against anonymous queries, and I think it also restricts the attributes available when a user without Editor rights (or above) queries other user accounts.
If you do not have administrative rights for the server, or a test server on which you can duplicate the problem, you will have to coordinate with the actual admins. You don't want to leave the LDAPDEBUG setting turned on longer than necessary.
Please see code below:
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DOMAINNAME"))
{
using(UserPrincipal qbeUser = new UserPrincipal(ctx))
{
using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
{
foreach (var found in srch.FindAll())
{
var user = (UserPrincipal)found;
Console.WriteLine(user.GivenName + " " + user.Surname + " " + user.EmailAddress);
}
}
}
}
If I do it like this it works fine, but I cannot specify the server name. Also not sure if it returns same results as the command line.
I tried using ValidateCredentials to check if the validation passes using my credential (using ContextType.Machine) but instead of returning true or false it throws the UnauthorizedAccessException.
I've tried accessing the domino server using a different method in .NET, unfortunately this one didn't worked either. (it thrown DirectoryServicesCOMException (A protocol error occurrred).
// create your "base" - the ou "formeremployees"
DirectoryEntry formerEmployeeOU = new DirectoryEntry("LDAP://HOSTNAME");
// create a searcher to find objects inside this container
DirectorySearcher feSearcher = new DirectorySearcher(formerEmployeeOU);
// define a standard ldap filter for what you search for - here "users"
feSearcher.Filter = "objectClass=*";
// define the properties you want to have returned by the searcher
feSearcher.PropertiesToLoad.Add("givenname");
feSearcher.PropertiesToLoad.Add("sn");
feSearcher.PropertiesToLoad.Add("mail");
feSearcher.PropertiesToLoad.Add("memberOf");
// search and iterate over results
foreach (SearchResult sr in feSearcher.FindAll())
{
//do something
}
return;
The quick solution for me is to run the ldapsearch command line tool.
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "ldapsearch";
p.StartInfo.Arguments = "-L -h hostname \"objectClass=*\" givenname sn mail";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
System.IO.File.WriteAllText(#"output.txt", output);
return;
Background:
I am using sql statements to create a Temp database on a server which will store data until it is needed further by my client program.
Problem:
My sql statement to create the database works properly and creates the database with all the required specifications when run through Sql Management studio, on the other hand when my program executes the statement it only creates a database with the 'Default' settings except for the name.
Questions:
Why is this?
How can I make it create a database with my specifications
Sql statement:
CREATE DATABASE Temp ON PRIMARY(
NAME = Temp
, FILENAME = 'C:\Temp.mdf'
, SIZE = 2MB
, FILEGROWTH = 10%) LOG ON (
NAME = Temp_Log
, FILENAME = 'C:\Temp.ldf'
, SIZE = 1MB, MAXSIZE = 70MB
, FILEGROWTH = 10%)
Code:
public void AcuConvert()
{
using (DestD)
{
SqlCommand command = new SqlCommand();
DestD.Open();
command.Connection = DestD;
foreach (var item in Entity.SqlDestinationQueries.ToList())
{
command.CommandText = item.Query;
command.ExecuteNonQuery(); //This is where the command is run
}
foreach (var item in Entity.SystemQueries.ToList())
{
command.CommandText = item.Query.Replace("#Sys", SysD.Database);
command.ExecuteNonQuery();
}
foreach (var item in Entity.InsertQueries.ToList())
{
command.CommandText = item.Query.Replace("#Source", SourceD.Database); ;
command.ExecuteNonQuery();
}
}
}
Have you tried using SQL Server Management Objects instead of a raw SQL statement?
For example:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
...
// Connect to the default instance
Server server = new Server();
// Establish new database details
Database database = new Database(server, "MyTempDB");
// Add primary filegroup details
database.FileGroups.Add(new FileGroup(database, "PRIMARY"));
// Set Primary datafile properties
DataFile primaryFile = new DataFile(database.FileGroups["PRIMARY"],
"MyTempDB_Data", "C:\\MyTempDB.mdf");
primaryFile.Size = 2048; // Sizes are in KB
primaryFile.GrowthType = FileGrowthType.Percent;
primaryFile.Growth = 10;
// Add to the Primary filegroup
database.FileGroups["PRIMARY"].Files.Add(primaryFile);
// Define the log file
LogFile logfile = new LogFile(database, "MyTempDB_Log", "C:\\MyTempDB_Log.ldf");
logfile.Size = 1024;
logfile.GrowthType = FileGrowthType.Percent;
logfile.Growth = 10;
logfile.MaxSize = 70 * 1024;
// Add to the database
database.LogFiles.Add(logfile);
// Create
database.Create();
database.Refresh();
You can connect to the server with specific credentials, too, of course:
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.server.aspx
If, however, you're stuck with using text scripts to create your database, I'd ensure that your Initial Catalog is set correctly (i.e. to 'master') in your connection string and your user has the necessary permissions - CREATE DATABASE / CREATE ANY DATABASE / ALTER DATABASE. If this still doesn't give you any joy, try stripping out the rest of your C# code and run the create SQL independently of the other statements - it could be that there's a side-effect from a preceding query. Use Profiler to see exactly what's running as you add them back in.
Edit:
I tested your script against a local SQL Server instance (2012 SqlLocalDB) via a small C# program using SqlClient and it ran just fine after changing the file paths to ones I had write access to (root of C is protected by default). The only other amendment was that the Primary size had to start at 3MB or more. Any smaller and the default tables could not be created. This may be another avenue of investigation for you to explore.
Your alternative option could be to use the Process class to run the sqlcmd.exe
Eg.
var process = Process.Start(WORKING_PATH, argument);
%WORKING_PATH% being "C:\tools\sql\sqlcmd.exe"
%argument% being "C:\scripts\Create.sql"
I use this strategy to dump test data into test environments when bootstrapping acceptance test fixtures.
Cheers
Title pretty much explains it all. I have a C# application that is not running on the Exchange Server. I need to be able to create mailboxes. I tried to use this tutorial, but it requires the PowerShell IIS Virutal directory to:
Not Require SSL
Allow Basic Authentication
Which are things that we cant do. This leads me to two possible solutions. Is there a way to modify the tutorial listed above to not require those two restrictions, or is there a way to do it without using power shell at all?
Here is the code, in case you dont feel like going to the link:
using System;
using System.Security;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace PowerShellTest
{
class Program
{
static void Main(string[] args)
{
// Prepare the credentials that will be used when connecting
// to the server. More info on the user to use on the notes
// below this code snippet.
string runasUsername = #"username";
string runasPassword = "password";
SecureString ssRunasPassword = new SecureString();
foreach (char x in runasPassword)
ssRunasPassword.AppendChar(x);
PSCredential credentials =
new PSCredential(runasUsername, ssRunasPassword);
// Prepare the connection
var connInfo = new WSManConnectionInfo(
new Uri("http://ServersIpAddress/PowerShell"),
"http://schemas.microsoft.com/powershell/Microsoft.Exchange",
credentials);
connInfo.AuthenticationMechanism =
AuthenticationMechanism.Basic;
// Create the runspace where the command will be executed
var runspace = RunspaceFactory.CreateRunspace(connInfo);
// generate the command parameters
var testNumber = 18;
var firstName = "Test";
var lastName = "User" + testNumber;
var username = "tuser" + testNumber;
var domainName = "pedro.test.local";
var password = "ActiveDirectoryPassword1234";
var ssPassword = new SecureString();
foreach (char c in password)
ssPassword.AppendChar(c);
// create the PowerShell command
var command = new Command("New-Mailbox");
command.Parameters.Add("Name", firstName + " " + lastName);
command.Parameters.Add("Alias", username);
command.Parameters.Add(
"UserPrincipalName", username + "#" + domainName);
command.Parameters.Add("SamAccountName", username);
command.Parameters.Add("FirstName", firstName);
command.Parameters.Add("LastName", lastName);
command.Parameters.Add("Password", ssPassword);
command.Parameters.Add("ResetPasswordOnNextLogon", false);
command.Parameters.Add(
"OrganizationalUnit", "NeumontStudents");
// Add the command to the runspace's pipeline
runspace.Open();
var pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(command);
// Execute the command
var results = pipeline.Invoke();
runspace.Dispose();
if (results.Count > 0)
Console.WriteLine("SUCCESS");
else
Console.WriteLine("FAIL");
}
}
}
You can set up a so-called runspace with many different AuthenticationMechanism's
Visit the MSDN site for code samples using:
Basic Authentication (which is used in your example)
Certificate Authentication
Kerberos Authentication
Negotiated Authentication
http://msdn.microsoft.com/en-us/library/ff326159(v=exchg.140).aspx
In any case, no need to give up on PowerShell just yet.
The code from that blog post is a little broken. The Pipeline class is an overly complex way to create a command, and the way that it's written involves creating a pair of runspaces (one local, one remote), instead of just the remote one.
Additionally, "Basic" and "http" in IIS do not mean "no security and no encryption in PowerShell". Everything sent over the WinRM layer is encrypted by default.
This Link from the Exchange Team covers the right way to do this in C# fairly well.
So:
You don't have to worry about the IIS "Basic", because there's another layer of security.
You can cut your code in half and make it faster if you use the C# from the Exchange team
Also to be 100% crystal clear:
You cannot manage Exchange 2010 remotely except thru PowerShell.
Hope This Helps