How can I remove user local account of administrators group with the help of WMI in C#. (NOT using System.DirectoryServices and System.DirectoryServices.AccountManagement).
I have tried this code. but I don't know how to run it.
using (var myDeleteUser = new StreamWriter("DeleteUser.vbs"))
{
myDeleteUser.WriteLine("Set objAdminGroup = GetObject(\"WinNT://" + hostHame + "/" + Settings.AdministratorsGroup + ",group\")");
myDeleteUser.WriteLine("Set objUser = GetObject(\"WinNT://" + domain + "/" + userName + ",user\")");
myDeleteUser.WriteLine("objAdminGroup.Remove(objUser.ADsPath)");
}
EDIT:
I try to do this:
Process proc = new Process();
proc.StartInfo.FileName = "DeleteUser.vbs";
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;
proc.Close();
But I have an error(vbs permission denied Getobject) in VBS file.
You want the Win32_UserAccount
Note the c# code implementation here - the delete on top of should be trivial
Enumerate Windows user group members on remote system using c#
Are you looking at deleting the account, or just remove from that group?
If you want to remove from the group check out the Win32_GroupUser object.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394153%28v=vs.85%29.aspx
Related
I have the following code for converting xml to csv by using perl script. When I run the perl script through c# but there is no files are created and string output become empty.
What is the problem?
I have the perl script with .txt extention, Is this ok or not?
string filePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/Files/SAVVIS_CDR_1806012231.XML";
if (Path.GetExtension(filePath) != "csv")
{
ProcessStartInfo perlStartInfo = new ProcessStartInfo(#"C:\Strawberry\perl\bin\perl.exe");
string perlScriptFilePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/PerlScript/formatter_savvis.pl.txt";
string csvFilePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/PerlScript/";
perlStartInfo.Arguments = perlScriptFilePath + " " + filePath + " " + csvFilePath;
perlStartInfo.UseShellExecute = false;
perlStartInfo.RedirectStandardOutput = true;
perlStartInfo.RedirectStandardError = true;
perlStartInfo.CreateNoWindow = false;
Process perl = new Process();
perl.StartInfo = perlStartInfo;
perl.Start();
perl.WaitForExit();
string output = perl.StandardOutput.ReadToEnd();
}
Could you please anyone help me to solve this problem?
Thanks in advance.
First, to find out what went wrong:
string error = perl.StandardError.ReadToEnd();
Also, make sure you have necessary permissions to create files in the output directory. You may try to run your process with Admin privileges to find out if it's a permission issue:
perlStartInfo.Verb = "runas";
You may want to run your entire host process with elevated permissions for this.
(This is only to figure out if it's a permission issue! If it's the case, grant the output directory the necessary permissions, and if possible don't automatically run scripts with admin privileges in production environment)
There also may be errors in the perl script itself.
I want to start another program which runs as user from a program running as administrator.
The problem is that the second program needs to use outlook, which is not possible if the program runs as admin. The main program needs to run as admin.
I did already come up with this two solutions:
Process.Start("cmd.exe", #"/C runas.exe /savecred /user:" + Environment.UserDomainName + "\\" + Environment.UserName + " " + "\"SomeProgram.exe" + "\"");
or
Process.Start("explorer.exe", "SomeProgram.exe");
But i have a problem with both solutions.
The first one asks the user for the password (only the first time after windows was restarted).
The second one probalby won`t work in the future, because as far as i found out it is considered as a bug and probably fixed with an future update.
So I would like to know is there any other solution, where the user does not need to enter his password?
This seems to work for me:
Process.Start("cmd.exe", #"/C runas.exe /TrustLevel:0x20000 " + "\"SomeProgram.exe" + "\"");
Process class has StartInfo property that is an instance of ProcessStartInfo class. This class exposes UserName, Domain and Password members to specify the user you want to run the process.
Process myProcess = new Process();
myProcess.StartInfo.FileName = fileName;
myProcess.StartInfo.UserName = userName;
myProcess.StartInfo.Domain = domain;
myProcess.StartInfo.Password = password;
myProcess.Start();
I was having the same issue and was not able to get the current logged user. NB: querying wmi is not a solution as many users may be logged in at that time
so my solution is to do the reverse. Launch my app as current user and if the current user is not admin, I request to run as admin.
if (IsAdministrator())
{
// run whatever you want as elevated user
}
else
{
//launch the same app as admin
ExecuteAsAdmin(PATHH_TO_THE_SAME_APP.EXE);
//execute whatever you want as current user.
}
public static void ExecuteAsAdmin(string fileName)
{
Process proc = new Process();
proc.StartInfo.FileName = fileName;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
}
public static bool IsAdministrator()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
I have a very simple C# web service written to handle offline domain joins for Windows builds. Part of the offline domain join provision process is the creation of a .txt file that is then retrieved later in the process. I have this web service dropping the .txt file in a folder that is locally on the web server which is a UNC share. For some reason when I make a rest call to this service passing the parameter, the service tries to put the .txt file on my local machine in that directory, which doesn't exist so it errors out. Why is it trying to put it on the machine of the box making the rest call, rather than locally? Here is the pertinent code:
public string ODJComputerName(string computername)
{
ProcessStartInfo startInfo;
Process process;
string path = Server.MapPath(".");
string share = Server.MapPath("~");
startInfo = new ProcessStartInfo(path + #"\djoin.exe");
startInfo.WorkingDirectory = share + #"\ODJ_files\";
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = true;
string outFile = startInfo.WorkingDirectory + computername + ".txt";
startInfo.Arguments = "/provision /domain mydomain.com /machine " + computername + " /reuse /savefile " + outFile;
process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit(60000);
I have a Windows Service which goes and update some files on the Network which is mapped as drive "Z:\". When i run the code from VS as administrator I am able to copy the file on the mapped drive but same thing fails when it is run from the Service which is running under administrator account.
The Mapped drive is created from same account under which service is running. Bit puzzling why its working when run from the VS but not from service.
Is it better to use UNC than network drive.
There is a workaround at below forum
http://support.microsoft.com/default.aspx?scid=kb;en-us;827421#appliesto
but it has used UNC not mapped drive.
We experienced this as well, and while I can't tell you WHY our resolution worked, i can tell you WHAT worked.
Map the drive in the code. Don't rely on the drive being mapped just because you're using the same account.
Based on the behavior we saw, this is what i would GUESS was happening in our situation and what's happening in yours.
The service we had issues with used a drive that was mapped in a login script. If we had the machine logged in as the same user the service was using, it worked, but if not it wouldn't work. Based on that, I surmised that the drive simply isn't mapped because the service doesn't really "log on".
Mapping the drive in code fixed it.
As a side note, you can also reference the UNC path directly, but we had permissions issues with that as well. Mapping the drive, passing in a username and password worked much better for us.
Our code for doing this:
public static class NetworkDrives
{
public static bool MapDrive(string DriveLetter, string Path, string Username, string Password)
{
bool ReturnValue = false;
if(System.IO.Directory.Exists(DriveLetter + ":\\"))
{
DisconnectDrive(DriveLetter);
}
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "net.exe";
p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username;
p.Start();
p.WaitForExit();
string ErrorMessage = p.StandardError.ReadToEnd();
string OuputMessage = p.StandardOutput.ReadToEnd();
if (ErrorMessage.Length > 0)
{
throw new Exception("Error:" + ErrorMessage);
}
else
{
ReturnValue = true;
}
return ReturnValue;
}
public static bool DisconnectDrive(string DriveLetter)
{
bool ReturnValue = false;
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "net.exe";
p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE";
p.Start();
p.WaitForExit();
string ErrorMessage = p.StandardError.ReadToEnd();
string OuputMessage = p.StandardOutput.ReadToEnd();
if (ErrorMessage.Length > 0)
{
throw new Exception("Error:" + ErrorMessage);
}
else
{
ReturnValue = true;
}
return ReturnValue;
}
}
Using the above class, you can map and disconnect the drive at will. If this is a service, I would recommend mapping the drive just before you need it and disconnecting the drive immediately after you need it.
I would suggest UNC is a better idea.
What if the mapped drive is mapped on login? A service may run without a user even logging in so the mapping might never be created.
I struggled a lot (~3 days) to solve the same issue. Seems it is more related to NTFS and file level permissions. It is better if you use shared location rather than a drive.
I'm working on a .NET class that will be used in tools to manage our Active Directory accounts. Each of our accounts gets a network home directory, which can be located on a couple different servers, depending on what type of account we're working with.
I can create and delete the folders just fine, but I'm running into trouble sharing the folders. I found some code here that seems to be what I want, but it isn't working properly for me. The return value I get is 2, but I'm not sure what that indicates.
This shouldn't be a file permission issue, since I'm running my test application as myself, and I have full control of the folder that I'm trying to share (and each of its parent folders).
Here's my (modified) version of the code:
char[] delim = { '\\' };
// folderPath is a string (UNC path)
string[] drivePath = folderPath.Split(delim);
// Create a ManagementClass object
ManagementClass managementClass = new ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams =
managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = "";
inParams["Name"] = drivePath[3];
inParams["Path"] = folderPath;
inParams["Type"] = 0x0; // Disk Drive
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams, null);
I've tried outputting the other outParams, but it looks like ReturnValue is all I get.
Is there a different way to share a remote folder that would work better?
I'll answer myself, in case someone else finds this later.
I ended up going with the extremely unsexy answer of using PSExec and NET SHARE:
// Retrieve drive path from AD
char[] delim = { '\\' };
string[] drivePath = userAD.HomeDirectory.Split(delim);
// Configure startup properties of process
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.FileName = "C:\\Windows\\System32\\psexec.exe";
// Build arguments for folder on alpha or student
startInfo.Arguments = "\\\\" + serverName + " -s net share " + shareName + "=" folderPath + "$ /GRANT:\"authenticated users\",full";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Note that in our environment the program will already be running under a user who has Full Control permissions on the folder being shared. To allow similar for a non-privileged user, you have to specify a name and password in startInfo.Arguments.