I have an application, that needs to get the last shutdown time. I have used EventLog class to get the shutdown time. I have separate class file that is designed to read/write event log. ReadPowerOffEvent function is intended to get the power off event.
public void ReadPowerOffEvent()
{
EventLog eventLog = new EventLog();
eventLog.Log = logName;
eventLog.MachineName = machineName;
if (eventLog.Entries.Count > 0)
{
for (int i = eventLog.Entries.Count - 1; i >= 0; i--)
{
EventLogEntry currentEntry = eventLog.Entries[i];
if (currentEntry.InstanceId == 1074 && currentEntry.Source=="USER32")
{
this.timeGenerated = currentEntry.TimeGenerated;
this.message = currentEntry.Message;
}
}
}
}
But whenever it tries to get the event entry count, it throws an IOException saying "The Network Path Not found". I tried to resolve, but I failed. Please help me out...
I think you sent wrong Log name, this worked for me
EventLog myLog = new EventLog();
myLog.Log = "System";
myLog.Source = "User32";
var lastEntry = myLog;
EventLogEntry sw;
for (var i = myLog.Entries.Count -1 ; i >=0; i--)
{
if (lastEntry.Entries[i].InstanceId == 1074)
sw = lastEntry.Entries[i];
break;
}
}
You have to have the "Remote Registry" service running on your machine (or the machine you want to run this app on). I suspect that this service in set to manual start on your machine. You may have to change the setting on this service to automatic.
If this app is going to be running on other machines, you may want to put some logic into your app to check to make sure this service is running first. If it isn't then you will need to start it up through your app.
Note:
The "Remote Registry" service enables remote users to modify registry setting on your computer. By default, the "Startup type" setting for the "Remote Registry" service may be set to "Automatic" or "Manual" which is a security risk for a single user (or) notebook PC user.
So, to make sure that only users on your computer can modify the system registry disable this "Remote Registry" service.
Related
I have a service that I wrote that I need to deploy to a number (about 1100) devices. All of these devices are logged in as a regular user, not an administrator.
I can push out the service with our deployment software, which does run as an admin. Our security team does not want this service to run on the Local System account (for obvious reasons). What I've come up with is that the service will install as the Local System, but will then change it's log in account to a virtual user, which then needs access to a folder in Program Files (x86).
What I've found is that if I install the service (using remote admin access) via the command line, I can install the service, but it won't start.
When I look in the event logs, I get an UnauthorizedAccessException error.
This I suspect is because the service is already running under the virtual user which doesn't have access to start the service. So how can I get around this?
In the main class for the service, I have this method, which is supposed to give the user access to the necessary folder:
private void GiveDirectoryAccess(string dir, string user)
{
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(dir);
DirectorySecurity ds = directoryInfo.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.FullControl,
InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
directoryInfo.SetAccessControl(ds);
}
catch (Exception e)
{
SimpleLog.Log(e);
throw;
}
}
This is called right after the service is initialized:
public CheckRALVersionService()
{
InitializeComponent();
// Give directory access
string alhadminPath = System.IO.Path.Combine(pathToFolder, alhadmin);
GiveDirectoryAccess(alhadminPath, serviceUser);
string exeName = System.IO.Path.GetFileName(fullExeNameAndPath);
string tmppath = System.IO.Path.Combine(localdir, tmp);
SimpleLog.SetLogFile(logDir: tmppath, prefix: "debout." + exeName + "_", extension: "log");
watcher = new DirectoryWatcher(pathToFolder, alhadmin);
}
Then, in the ProjectInstaller class, I am changing the user to the virtual user in the serviceInstaller1_Committed method:
void serviceInstaller1_Committed(object sender, InstallEventArgs e)
{
using (ManagementObject service = new ManagementObject(new ManagementPath("Win32_Service.Name='RalConfigUpdate'")))
{
object[] wmiParams = new object[11];
wmiParams[6] = #"NT Service\RalConfigUpdate";
service.InvokeMethod("Change", wmiParams);
}
}
Do I need a helper service to give the access? Can what I want to do be done all within this service?
Thanks in advance.
One option could be to grant the regular user, the permission to start & stop the service.
There is a little tool from Microsoft for that purpose: SubInAcl!
Set Windows Service Permission!
There should be the possibility to do so using group policies as well. That should be a better approach for your use case. On the other hand, the SubInAcl method is easier to test for you. I found an older description here!
To strictly respond to your question:
You can use
System.Io.File.GetAccessControl to get a FileSecurity Class tha can be used to modify the Permissions on filesystem.
The links show some good examples.
BUT that will works ONLY if the user that will run the process will have the right to CHANGE the PERMISSIONS from Windows, if not ====> UnauthorizedAccessException
After sitting on this for a bit, I found a solution. It may not be the most elegant, but it should work for my purposes. I had all of the "parts", but was just doing things in the wrong order.
Previously, I was trying to change the user during the install process, which wasn't working. What I ended up doing was allow the service to install as the LOCAL SYSTEM account, and then change to the virtual account user during the OnStart method of the actual program.
So:
protected override void OnStart(string[] args)
{
string alhadminPath = System.IO.Path.Combine(pathToFolder, alohadmin);
try
{
// Update the service state to start pending
ServiceStatus serviceStatus = new ServiceStatus
{
dwCurrentState = ServiceState.SERVICE_START_PENDING,
dwWaitHint = 100000
};
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
// Update the logs
eventLog1.WriteEntry("Starting Service", EventLogEntryType.Information, eventId++);
SimpleLog.Info("RAL Config Update Service started");
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
// Change the user to the virutal user
using (ManagementObject service = new ManagementObject(new ManagementPath("Win32_Service.Name='RalConfigUpdate'")))
{
object[] wmiParams = new object[11];
wmiParams[6] = serviceUser;
service.InvokeMethod("Change", wmiParams);
}
GiveDirectoryAccess(alhadminPath, serviceUser);
}
catch (Exception e)
{
eventLog1.WriteEntry("Service failed to start", EventLogEntryType.Error, eventId++);
SimpleLog.Log(e);
throw;
}
}
This is working the way it should, and should also satisfy the security procedures. Thanks everyone.
Attempting to pull the automatic update settings from the registry of a remote server. For some reason, it's returning a 0 even though a manual check of the key is 1-4. What am I overlooking? Snippet below:
ManagementScope msAutoUpdateReg = new ManagementScope(#"\\" + remoteServer + #"\root\DEFAULT:StdRegProv", connection);
msAutoUpdateReg.Connect();
ManagementClass ci = new ManagementClass(msAutoUpdateReg, new ManagementPath(#"DEFAULT:StdRegProv"), new ObjectGetOptions());
ManagementBaseObject inParams = ci.GetMethodParameters("GetDWORDValue");
inParams["hDefKey"] = 0x80000002; //HKLM
inParams["sSubKeyName"] = #"Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update";
inParams["sValueName"] = "AUOptions";
ManagementBaseObject outParams = ci.InvokeMethod("GetDWORDValue", inParams, null);
UInt32 auValue = (UInt32)outParams["uValue"];
if (auValue.ToString() != "0")
{
if (auValue == 1)
{
string currentSetting = "Keep my computer up to date has been disabled in Automatic Updates.";
}
if (auValue == 2)
{
string currentSetting = "Notify of download and installation.";
}
if (auValue == 3)
{
string currentSetting = "Automatically download and notify of installation.";
}
if (auValue == 4)
{
string currentSetting = "Automatically download and scheduled installation.";
}
}
else
{
string currentSetting = "Unknown";
}
I guess a process of elimination might help here...
1) Is this happening on just one server or are you getting this on all servers? How about on your own local machine? Is it a Windows version thing? For example it seems my Windows 10 box doesn't show the SubKey name you are looking for.
2) Do you also get zero if you change the sValueName to "foo"? Is a value of 0 representing an error?
3) Can you put a watch on outParams and check to see what values have been returned?
4) Are you being blocked by UAC, firewall or other permission issues? Can you execute other WMI commands against this server without any problems? Do you need to Run As Administrator to get this to work?
5) Are you getting an other exceptions or return values? I'm guessing you've posted just a portion of the code here so is this code inside a try/catch block?
Sorry if this sounds either vague or simplistic but I think you may need to look at what does work and what doesn't to see if you can identify a pattern.
I have an Outlook add-in that is working successfully for about 100 users. It interacts with our application and creates/updates Tasks and Appointment items. However, one client cannot get it to work for anyone who is not a network administrator. Through some logging, I can see that it works fine until it gets to the part where it should save the Task, and then it throws the infamous "The operation failed." error. I have tried in vain to get more error details by investigating inner exceptions and such, but "The operation failed." is all I can seem to get out of it.
To make it simpler to debug, I eliminated our application from the picture and wrote them a test add-in that just creates 9 tasks (hard-coded to "Task 1", "Task 2", etc.) and it fails in the same place with the same error. I have asked them to write a macro to see if a macro is able to create tasks for these users. I am awaiting their reply on that.
Anyway, I have been on MSDN for over a month trying to get help on the issue and nobody has been able to help. I am hoping someone here could shed some light. If you can provide any insight on what might be happening or suggestions to help me track down the problem, it would be greatly appreciated!
This is the function I am using to create the sample tasks in the test add-in:
private void CreateTasks()
{
int i = 1;
Outlook.TaskItem t = null;
Outlook.UserProperties ups = null;
Outlook.UserProperty up = null;
string name = string.Empty;
while (i < 10)
{
name = string.Format("Task {0}", i.ToString());
t = Application.CreateItem(Outlook.OlItemType.olTaskItem);
t.Subject = name;
t.Status = Outlook.OlTaskStatus.olTaskNotStarted;
t.Body = string.Format("Task {0} description", i.ToString());
t.Categories = "Test Task";
t.Importance = Outlook.OlImportance.olImportanceNormal;
t.ActualWork = 0;
t.TotalWork = 5 * 60;
//mimic dates that might come in main add-in
DateTime st = Convert.ToDateTime("12/10/2013");
st = st.AddDays(i);
t.StartDate = st;
DateTime end = Convert.ToDateTime("01/02/2014");
end = end.AddDays(i);
string EP = end.ToShortDateString() + " 5:00:00 PM";
end = Convert.ToDateTime(EP);
t.DueDate = end;
//mimic how we keep track of our items in the main add-in
ups = t.UserProperties;
up = ups.Find("ID");
if (up == null)
{
up = ups.Add("ID", Outlook.OlUserPropertyType.olText);
}
up.Value = string.Format("ID {0}", i.ToString());
//This is where the "The Operation Failed." error occurs on every single task.
try
{
((Outlook._TaskItem)t).Save();
}
catch (Exception ex)
{
//logs message to file
}
//Release objects
if (up != null) Marshal.ReleaseComObject(up);
if (t != null) Marshal.ReleaseComObject(t);
i++;
}
GC.Collect();
}
According to MSDN:
Saves the Microsoft Outlook item to the current folder or,
if this is a new item, to the Outlook default folder for the item type.
Does the "non administrator user" have access to this folder?
I'd hedge a bet it is something to do with Access permissions. This would be the first place to start.
Is this in an Exchange mailbox? I've seen this error before when connection to the server becomes spotty. If it is, see if the error occurs if you switch from cached mode to online mode. I don't think it's a code issue.
I am trying to write an applicaiton that will run as a scheduled task on the vCenter server and will monitor the current time of each host in my cluster. The time is set by NTP but I am seeing VM servers running on these hosts going out by up to a minute and need to monitor what happens.
My hosts are running ESXi v5.1
According to the documentation (http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.DateTimeSystem.html#queryDateTime) there is a method that gets the current DateTime of a host - QueryDateTime().
I am struggling to get this to work though.... my sample code is below. It always complains about the QueryDateTime method not existing!
This is likely me not understanding the SDK, but I can't figure this out.....
VimClient vimClient = new VimClient();
vimClient.Connect(vcenter.ServiceURL);
vimClient.Login(vcenter.Username, vcenter.Password);
List<EntityViewBase> hosts = vimClient.FindEntityViews(typeof(VMware.Vim.HostSystem), null, null, null);
foreach (HostSystem host in hosts)
{
Console.WriteLine(host.Config.Network.Vnic[0].Spec.Ip.IpAddress);
HostConfigManager hostConfigManager = host.ConfigManager;
HostDateTimeSystem hostDateTimeSystem = hostConfigManager.DateTimeSystem;
DateTime hostDateTime = hostDateTimeSystem.QueryDateTime();
}
You should try this.
foreach (HostSystem host in vmHosts)
{
HostConfigManager hostConfigManager = host.ConfigManager;
HostDateTimeSystem hostDateTimeSystem = (HostDateTimeSystem) vimClient.GetView(hostConfigManager.DateTimeSystem, null));
DateTime hostDateTime = hostDateTimeSystem.QueryDateTime();
}
I have an event receiver that is using the ItemUpdating event. I am trying to disinherit the item's permissions from parent and strip all permissions on the item upon being uploaded to the Drop Off Library. The reason for this is that the document contains sensitive information and should not be visible to anyone once it arrives in the Drop Off Library.
The code below is throwing the following error when executing the CurrentListItem.BreakRoleInheritence(true) line upon reaching the Drop Off Library: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite oSiteCollection = new SPSite(properties.ListItem.Web.Url))
{
using (SPWeb oWebsite = oSiteCollection.RootWeb)
{
SPListItem CurrentListItem = properties.ListItem;
SPRoleAssignmentCollection SPRoleAssColn = CurrentListItem.RoleAssignments;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
CurrentListItem.BreakRoleInheritance(true);
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)
{
if (SPRoleAssColn[i].Member.Name != "System Account")
{
SPRoleAssColn.Remove(i);
}
}
}
}
});
I have also done the following things:
- made sure the Identity of the app pool is a site collection admin
- tried to get the list item again using GetItemById (but this throws an error that the item does not exist, since the item has still not been published yet - we need to remove permissions before the document is published - and we cannot force a check-in otherwise the drop off library might process and move the document to the its target library)
- tried getting the web and site options using guids
- tried many different combinations of placements with AllowUnsafeUpdates
- used the user token of a site collection admin to open the web objects
For some reason, the code above works fine when the document reaches the target library (as we are removing all the permissions AGAIN once the document arrives at the destination). This happens because the document is moved from the drop off library to the target library using the System Account.
Any thoughts on how to get around the "Access is Denied" error while utilizing a similar approach as above?
And how this item is being sent to Drop off library? Via workflow, or when using OfficialFile.asmx? Can you check if this eventreceiver works properly when you manually upload file (most probably you will have to click 'submit' to force update, but maybe you can set fields in such way, that none of your Rules would match? I files get there via workflow, make sure that also account on which SPTimer4 service is running is site administrator on this site collection.
Also be careful, - i think there are two things that may not work as you expect in your event receiver:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (var oSiteCollection = new SPSite(properties.ListItem.Web.Url))
{
using (var oWebsite = oSiteCollection.RootWeb)
{
var currentListItem = properties.ListItem;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
currentListItem.BreakRoleInheritance(true);
//You should take the RoleAssignments after breaking inheritance our you will be working on parents permissions.
var spRoleAssColn = currentListItem.RoleAssignments;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
for (int i = spRoleAssColn.Count - 1; i >= 0; i--)
{
//I think it won't allow you to remove permissions for site administrator
if (spRoleAssColn[i].Member.Name != "System Account" && !oWebsite.EnsureUser(spRoleAssColn[i].Member.LoginName).IsSiteAdmin)
{
spRoleAssColn.Remove(i);
}
}
}
}
});