Get-MsolUser command error from C# - c#

I am trying to execute a piece of Azure script to check if the user object is synced from on-prem AD to Azure as below.
username follows the pattern of a UPN. example: john.Smith#ed.com
//Check Azure to see if user is synced to office 365
private static bool IsAccountSyncedToOffice365(string username)
{
StringBuilder cmd = CreateAzureConnectScript();
//cmd.AppendLine("Get-MsolUser -UserPrincipalName " + username + " -ErrorAction SilentlyContinue");
cmd.AppendLine("$global:res = \"false\"");
cmd.AppendLine("$global:user = \"false\"");
cmd.AppendLine("try{ if(($global:user=Get-MsolUser -UserPrincipalName " + username + " -ErrorAction Stop).ImmutableId -ne $null) { $global:res = \"true\"} } Catch { $global:errorMessage = $_.Exception.Message}");
try
{
Collection<PSObject> results;
string output, error, errorMessageAzureCnn = "";
do
{
results = null;
output = "";
error = "";
var rs = CreateAzureRunspace();
var pipe = rs.CreatePipeline();
pipe.Commands.AddScript(cmd.ToString());
results = pipe.Invoke();
output = (rs.SessionStateProxy.PSVariable.GetValue("res")) != null ? rs.SessionStateProxy.PSVariable.GetValue("res").ToString() : "false";
error = (rs.SessionStateProxy.PSVariable.GetValue("errorMessage")) != null ? rs.SessionStateProxy.PSVariable.GetValue("errorMessage").ToString() : "null";
errorMessageAzureCnn = (rs.SessionStateProxy.PSVariable.GetValue("errorMessageAzureCnn")) != null ? rs.SessionStateProxy.PSVariable.GetValue("errorMessageAzureCnn").ToString() : "null";
ExceptionManager.Publish(new Exception("LOG: Queried Azure at:" + DateTime.Now + " for user:" + username + " Result: " + output + " Error: " + error + " errorMessageAzureCnn: " + errorMessageAzureCnn));
Thread.Sleep(60000); //sleep for 60 seconds
pipe.Dispose();
rs.Close();
rs.Dispose();
} while (output.Trim().ToLower() != "true");
ExceptionManager.Publish(new Exception("LOG: " + username + " is found synced to Azure at: " + DateTime.Now));
cmd.Clear();
return true;
}
catch (Exception ex)
{
ExceptionManager.Publish(new Exception("Error checking Azure to see if the user is synced to office 365 or not.. " + ex.Message));
throw ex;
}
}
private static StringBuilder CreateAzureConnectScript()
{
StringBuilder ss = new StringBuilder();
MSCredential cred = new MSCredential();
var username = cred.username;
var pwd = cred.password;
try
{
ss.AppendLine("try {");
ss.AppendLine("$password = ConvertTo-SecureString \"" + pwd + "\" -AsPlainText –Force");
ss.AppendLine("$credential = New-Object System.Management.Automation.PsCredential(\"" + username + "\",$password)");
ss.AppendLine("$cred = Get-Credential -cred $credential");
ss.AppendLine("Import-Module MSOnline");
ss.AppendLine("Start-Sleep -s 10");
ss.AppendLine("Connect-Msolservice -cred $cred");
ss.AppendLine("} Catch { $global:errorMessageAzureCnn = $_.Exception.Message }");
//ExceptionManager.Publish(new Exception("LOG:pwd: " + pwd + " uname:" + username));
return ss;
}
catch (Exception ex)
{
ExceptionManager.Publish(new Exception("Error enabling the remote mailbox.. " + ex.Message));
throw ex;
}
}
While the script executes successfully through Powershell Window on the same server having got all the latest versions of the modules installed. When trying to execute the same command from C# code it throws the below exception collected from the powershell exception handling $global:errorMessage = $_.Exception.Message.
Show Details Exception (0): [] LOG: Queried Azure at:7/30/2015 12:00:55 PM for user:testuser0385#xxx.com Result: false Error: You must call the Connect-MsolService cmdlet before calling any other cmdlets. errorMessageAzureCnn: null
Worth mentioning that I have got the same code as below working in one server but it is throwing the below error on a production server (Windows Server 2008 R2 Datacenter) and only via the code it is happening. via the powershell window it works perfectly fine.
Good to know your thoughts about what looks wrong or needed to be looked into.
Thanks!

It suggests that the sign in is failing, but you're pushing on with the Get-MsolUser anyway. The Connect-MsolService cmdlet fails if it cannot communicate to the Microsoft Online Services Sign-In Assistant. Ref: https://community.office365.com/en-us/f/156/t/252201
Has the production server got all the pre-requisites installed: Microsoft Online Services Sign-In Assistant and .NET 3.5? We had a problem in production (Azure PAAS) where the guest OS image was automatically updated and was missing .NET 3.5, which broke our Azure AD PowerShell processes.

Related

Error call to SSPI with my WebService in C#

I am developing a WebService in C # however I am facing an error.
This is the error :
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message or signature supplied for verification has been altered
So I sometimes get this error when I open my MySQL connection in my WebService.
I had this error by launching my webService twice at the same time then I tried again and no more errors.
My web service is on a Windows server 2012 R2 and i'm using .NET Framework 4.7.2 (It is called by the website php).
I did quite a bit of internet research and came across this in C# :
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
But it doesn't work, Do you have any idea so that I do not face this problem again ?
There is my MySQL open connection method :
public MySqlConnection OpenConnectionDB(string clientId)
{
listVerifs = new List<string>();
int iConn = 0;
try
{
MySqlConnection sqlCo = new MySqlConnection("server=MyServer;database=" + this.db + ";username=MyUID;password=MyPwd;AllowLoadLocalInfile=true");
if (sqlCo.State != ConnectionState.Open)
{
sqlCo.Open();
}
listVerifs.Add("CO SQL");
dataSourceDBF = #"//ntserver/Winbooks_Data/winbooks/data/" + clientId + "/";
dbfCo = new AdsConnection(#"data Source=//ntserver/Winbooks_Data/winbooks/data/" + clientId + "/" + clientId + ".add;User ID=mYUID;Password=;ServerType=local;ReadOnly=true;pooling=true;TrimTrailingSpaces=true;TableType=CDX;LockMode=COMPATIBLE");
if (dbfCo.State == ConnectionState.Closed)
{
dbfCo.Open();
}
listVerifs.Add("CO DBF");
Console.WriteLine("Databases connections open succesfull");
return sqlCo;
}
catch (Exception e)
{
dbfCo = null;
Console.WriteLine("Error connection " + e.Message);
test = e.Message;
log.AddLog("Erreur Fonction OpenConnectionDB : " + e.ToString(), 3, "WebServiceMySQL");
return null;
}
Thank's in advance !

VB / C# Query Event Logs from Domain Controller by looking at username in EventData

I am attempting to have specific event logs that contain a username that are Security Audit Failures from a DC, in powershell I can easily do this with something like this:
Where the variables would be something like: $DC = "MyDomainController" and $user = "jdoe"
Get-WinEvent -ComputerName $DC -FilterHashtable #{Logname='Security';Keywords='4503599627370496';Data=$user} -MaxEvents 4 | Format-List -Property ID, TimeCreated, MachineName, Message
This would pull 4 event logs that are security audit failures with the person's username from a DC I am looking at, however I have been unable to find or reproduce this behavior to something similar in vb.net, I have been searching pages for the last few days and coming up with a lot of writing and pulling all logs on DC's but not filtering down, any help or guidance would be great, thank you!
I was able to find the answer to this by looking at custom log query's by using xpath, I did the following in C# but the same can be applied in VB, Domaincontroller.text = The domain controller your looking up: Username.text = The AD username to lookup Statustextbox = I have all the logs go to a textbox to read but you could do something like console.writeline
private void LookupLogs_Click(object sender, EventArgs e)
{
Statustextbox.Clear();
string query = "<QueryList>" +
" <Query Id=\"0\" Path=\"Security\">" +
" <Select Path=\"Security\">" +
" *[System[band(Keywords,4503599627370496)]] and *[EventData[Data[#Name='TargetUserName'] and (Data='" + Username.Text + "')]]" +
" </Select>" +
" </Query>" +
"</QueryList>";
EventLogSession session = new EventLogSession(DomainController.Text);
EventLogQuery evntquery = new EventLogQuery("Security", PathType.LogName, query);
evntquery.Session = session;
try
{
EventLogReader logreader = new EventLogReader(evntquery);
DisplayEventAndLogInformation(logreader);
}
catch (Exception ex)
{
MessageBox.Show("An exception occured: " + ex.Message);
}
}
private void DisplayEventAndLogInformation(EventLogReader logReader)
{
for (EventRecord eventInstance = logReader.ReadEvent();
null != eventInstance; eventInstance = logReader.ReadEvent())
{
Statustextbox.AppendText(Environment.NewLine + Environment.NewLine);
Statustextbox.AppendText("---------------------------------------------------------------------------------------------------------------------------------------------------------------" + Environment.NewLine);
Statustextbox.AppendText("Event ID: " + eventInstance.Id + Environment.NewLine);
Statustextbox.AppendText("Publisher: " + eventInstance.ProviderName + Environment.NewLine);
try
{
Statustextbox.AppendText("Description: " + eventInstance.FormatDescription() + Environment.NewLine);
}
catch (EventLogException ex)
{
Statustextbox.AppendText("An exception was thrown: " + ex.Message + Environment.NewLine);
}
EventLogRecord logRecord = (EventLogRecord)eventInstance;
Statustextbox.AppendText(Environment.NewLine);
Statustextbox.AppendText("Container Event Log: " + logRecord.ContainerLog + Environment.NewLine);
}
}

Executing Process not working

The situation:
I want to modify the folder quotas on my FileServer through a process executing dirquota.exe
The Problem:
The Process being executed gives no result at all
So Far:
I've redirected the process and arguments being executed on my FileServer to take a closer look what's happening exactly on the serverside.
The executed process gave no exception and everything went just fine, it seemed..
When looking at the current folder quota's on my FileServer nothing has changed..I decided to copy paste my arguments in a CMD.exe on the server, then it all went fine...
I cannot figure why it is not working on my FileServer, probably somthing simple but I need some help here
Important Info:
I'm installing a Windows Service on my FileServer and calling the Method through SOUPUI (This is all working fine).
The installed service is running as a Domain admin and has all the required rights to perform these actions
The Class
public class Quota
{
public string FolderLocation;
public int SizeInMB;
public string FileServerName;
}
The Method
public string SetFolderQuota(Quota quota)
{
Process QuotaProcess = new Process();
QuotaProcess.StartInfo.RedirectStandardOutput = false;
QuotaProcess.StartInfo.FileName = #"cmd.exe";
QuotaProcess.StartInfo.UseShellExecute = true;
QuotaProcess.StartInfo.Arguments = "/C " + "dirquota Quota Add /PATH:" + '"' + quota.FolderLocation + '"' + " /Limit:" + quota.SizeInMB + "mb" + " /remote:" + quota.FileServerName;
try
{
QuotaProcess.Start();
}
catch(Exception Ex)
{
return Ex.Message;
}
return "Correctly Executed: " + QuotaProcess.StartInfo.FileName + QuotaProcess.StartInfo.Arguments;
}
Found The Problem
dirquota.exe is redirected using Windows-on Windows 64-bit redirection. What's happening is that my launch request (from a 32-bit process) is being redirected to %windir%\SysWOW64\dirquota.exe. Since there's no 32-bit version of this particular executable on 64-bit installs, the launch fails. To bypass this process and allow my 32-bit process to access the native (64-bit) path, I have to reference %windir%\sysnative instead
The Code
public string SetFolderQuota(Quota quota)
{
string FileLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),#"sysnative\dirquota.exe");
Process QuotaProcess = new Process();
QuotaProcess.StartInfo.RedirectStandardOutput = false;
QuotaProcess.StartInfo.FileName = FileLocation;
QuotaProcess.StartInfo.UseShellExecute = true;
QuotaProcess.StartInfo.Arguments = " Quota Add /PATH:" + '"' + quota.FolderLocation + '"' + " /Limit:" + quota.SizeInMB + "mb" + " /remote:" + quota.FileServerName;
try
{
QuotaProcess.Start();
}
catch(Exception Ex)
{
return Ex.Message + Environment.NewLine + "FileLocation: " + FileLocation;
}
return "Correctly Executed: " + QuotaProcess.StartInfo.FileName + QuotaProcess.StartInfo.Arguments;
}
Best if you can redirect the output of Process to a log file and see what is the actual exception..
ProcessStartInfo process = new ProcessStartInfo
{
CreateNoWindow = false,
UseShellExecute = false,
RedirectStandardOutput = true,
FileName = #"cmd.exe",
Arguments = "/C " + "dirquota Quota Add /PATH:" + '"' + quota.FolderLocation + '"' + " /Limit:" + quota.SizeInMB + "mb" + " /remote:" + quota.FileServerName
};
Process p = Process.Start(process);
string output = p.StandardOutput.ReadToEnd();
Log the value of output to get the exact exception caused by execution of this command

Connecting to Public Folders using RDO & MAPI

I am trying to connect to my companies Exchange 2003 server using RDO & MAPI which I've never done before. I have found a pretty good site that uses Outlook's Redemption (http://www.dimastr.com/redemption/home.htm) but with all of the examples on the site using VB.NET and me not being great at programming it's a bit difficult to get this working.
So far I have this code
static void ConnectToExchange()
{
object oItems;
//string outLookUser = "My Profile Name";
string outLookUser = "username#xxx.xxxx";
string ToEmailAddress = "username#xxxx.com";
string FromEmailAddress = "username#xxx.com";
string outLookServer = "xxservernamexx";
string sMessageBody =
"\n outLookUser: " + outLookUser +
"\n outLookServer: " + outLookServer +
"\n\n";
RDOSession Session = new RDOSession();
try
{
Session.LogonExchangeMailbox(outLookUser,outLookServer);
int mailboxCount = Session.Stores.Count;
string defaultStore = Session.Stores.DefaultStore.Name;
RDOFolder TestTaxCert = Session.GetFolderFromPath(#"\\Public Folders\All Public Folders\TestTaxCert");
}
catch (Exception ex)
{
Session = null;
//System.Web.Mail.SmtpMail.Send(ToEmailAddress, FromEmailAddress, "Error", sMessageBody + " " + ex.Message);
}
finally
{
if ((Session != null))
{
if (Session.LoggedOn)
{
Session.Logoff();
}
}
}
}
}
My problem is that once the program hits the Session.LogonExchangeMailbox(outLookUser,outLookServer); line, a prompt appears asking for my credentials (username, domain, password) and no matter what information I fed the prompt it denied permission.
SO if someone can help me with that and then also with connecting to the public folders...that'd be greaaat
Make sure your code is running as the domain user specified in the call to LogonExchangeMailbox.
Did you really mean 2003, or is it Exchange 2013?

running Add-mailboxpermission from aspx page with impersonation

I am trying to execute Add-Mailboxpermission from a ASPX page with impersonation of a specific user. an application error from MSExchange Common source is logged in the Event viewer of the web server.
Watson report about to be sent to dw20.exe for process id: 2992, with parameters: E12, c-buddy-RTL-AMD64, 08.03.0083.006, w3wp, M.E.D.Directory, M.E.D.D.ConnectionPoolManager.BlockImpersonatedCallers, M.E.Common.FailFastException, c84f, 08.03.0213.000. ErrorReportingEnabled: False
The same code for executing a different Exchange CMDlets including the impersonation call is used and completes without any error.
String ErrorText = "";
RunspaceConfiguration config = RunspaceConfiguration.Create();
PSSnapInException warning;
sDecryptedPwd = SecurityManager.Decrypt(AdminPassword, true);
using (new Impersonator(AdminUserName, "domain name", sDecryptedPwd))
{
// Load Exchange PowerShell snap-in.
config.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out warning);
if (warning != null)
throw warning;
using (Runspace thisRunspace = RunspaceFactory.CreateRunspace(config))
{
try
{
thisRunspace.Open();
using (Pipeline thisPipeline = thisRunspace.CreatePipeline())
{
//Please change parameter values.
thisPipeline.Commands.Add("Add-MailboxPermission");
thisPipeline.Commands[0].Parameters.Add("Identity", sMailboxName);
thisPipeline.Commands[0].Parameters.Add("User", sUserName);
thisPipeline.Commands[0].Parameters.Add("AccessRights", sAccessRights);
thisPipeline.Commands[0].Parameters.Add("DomainController", sDomainController);
iLogManager.Info("Identity: " + sMailboxName + " User: " + sUserName + " AccessRights: " + sAccessRights + " DomainController: " + sDomainController);
try
{
thisPipeline.Invoke();
iLogManager.Info(thisPipeline.Commands[0].CommandText);
}
catch (Exception ex)
{
ErrorText = "Error: " + ex.ToString();
}
// Check for errors in the pipeline and throw an exception if necessary.
if (thisPipeline.Error != null && thisPipeline.Error.Count > 0)
{
StringBuilder pipelineError = new StringBuilder();
pipelineError.AppendFormat("Error calling Add-MailboxPermission.");
foreach (object item in thisPipeline.Error.ReadToEnd())
{
pipelineError.AppendFormat("{0}\n", item.ToString());
}
ErrorText = ErrorText + "Error: " + pipelineError.ToString() + Environment.NewLine;
}
}
}
finally
{
thisRunspace.Close();
}
}
}
if (ErrorText == "")
return "no error occurred.";
else
return ErrorText;
Does Exchange allows impersonation of Exchange CMDlets that modifies ACL's or am I doing something wrong here..
Can anybody help me here, there is not much information about Exchange Powershell CMdlets with impersonation from ASPX page.

Categories

Resources