I am working on doing a check for Firewalls. The following code quite easily checks the status of the default Windows Firewall:
INetFwMgr manager = GetFireWallManager();
bool isFirewallEnabled = manager.LocalPolicy.CurrentProfile.FirewallEnabled;
if (isFirewallEnabled == false)
{
Console.WriteLine("Firewall is not enabled.");
}
else
{
Consoe.WriteLine("Firewall is enabled.");
}
Console.ReadLine();
private static INetFwMgr GetFireWallManager()
{
Type objectType = Type.GetTypeFromCLSID(new Guid(firewallGuid));
return Activator.CreateInstance(objectType) as INetFwMgr;
}
The question then becomes: How do I find the status of a non-Windows Firewall?
If the Firewall is properly integrated, will the above check work just the same or is there a better method for doing this?
I have checked this post: C# Windows Security Center Settings and this post: C# - How to chceck if external firewall is enabled? but both proved relatively unhelpful.
I have been looking into the WMI API but it is pretty confusing so far, and the documentation via MSDN hasn't been too promising.
I have also tried messing around with SelectQuery but so far I have been unsuccessful.
Can anyone assist me in a new starting point or to where I might be able to find better documentation/instructions concerning 3rd Party Firewalls?
EDIT: Currently I am exploring further into WMI, specifically the class FirewallProduct as suggested by a post.
UPDATE 2: I have been testing the following snippet:
string wmiNameSpace = "SecurityCenter2";
ManagementScope scope;
scope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", "localhost", wmiNameSpace), null);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM FirewallProduct");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
But running this results in the following error:
Exception Invalid namespace and it points to line 39 (scope.Connect()). I would not be at all surprised if I have simply missed a parameter or formatted something improperly, I just don't know what it is.
UPDATE 3 Switching from SecurityCenter2 to SecurityCenter still yields the same invalid namespace error.
UPDATE 4 I moved the console app over to a different box (win7 not winserver08r2) and it properly reported back as expected. So it may be an issue with the VM that I currently have been testing on. Next step is to parse out active/inactive status
UPDATE 5 It was tested on another Server08 box and the same invalid namespace error appears. Using SecurityCenter instead of SecurityCenter2 does not resolve the issue. Is there some underlying security feature Windows Server OS's use to prevent tampering with Firewalls, or do Server OS's not come with a specific key set of WMI features?
According to Microsoft Q: How does Windows
Security Center detect third-party products and their status?
A:
Windows Security Center uses a two-tiered approach for detection
status. One tier is manual, and the other tier is automatic through
Windows Management Instrumentation (WMI). In manual detection mode,
Windows Security Center searches for registry keys and files that are
provided to Microsoft by independent software manufacturers. These
registry keys and files let Windows Security Center detect the status
of independent software. In WMI mode, software manufacturers determine
their own product status and report that status back to Windows
Security Center through a WMI provider. In both modes, Windows
Security Center tries to determine whether the following is true:
An antivirus program is present.
The antivirus signatures are up-to-date.
Real-time scanning or on-access scanning is turned on for antivirus programs.
For firewalls, Windows Security Center
detects whether a third-party firewall is installed and whether the
firewall is turned on or not.
So you can use the WMI to determine if a third-party firewall is installed, using the FirewallProduct class, sometime ago I wrote an article about this topic which explain how obtain this info using the WMI.
Getting the installed Antivirus, AntiSpyware and Firewall software using Delphi and the WMI.
Try this sample C# to get the current Third-party firewall name and state installed.
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
class Program
{
static void Main(string[] args)
{
try
{
//select the proper wmi namespace depending of the windows version
string WMINameSpace = System.Environment.OSVersion.Version.Major > 5 ? "SecurityCenter2" : "SecurityCenter";
ManagementScope Scope;
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", "localhost", WMINameSpace), null);
Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT * FROM FirewallProduct");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
foreach (ManagementObject WmiObject in Searcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}","Firewall Name",WmiObject["displayName"]);
if (System.Environment.OSVersion.Version.Major < 6) //is XP ?
{
Console.WriteLine("{0,-35} {1,-40}","Enabled",WmiObject["enabled"]);
}
else
{
Console.WriteLine("{0,-35} {1,-40}","State",WmiObject["productState"]);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
Related
I am trying to query the local machine for information about the status of the different services in windows security, such as windows defender and the firewall, using WMI from system.management. For testing purposes I am working in a console project and I am just trying to access MSFT_MpComputerStatus and properties like AMServiceEnabled, but no matter what i do an exception is thrown when a try to foreach through the collection.
I am a very new to WMI so it might just be something i have missed but I have been trying to get this to work for a few days now.Through my search i found a few different code examples showing how to access properties of classes, such as:
(For finding everything in a class)
(For accessing properties on a specific ManagementObject instance)
(Using the WMI code creator tool was suggested here)
I tried all of these using the namespace: root\\Microsoft\\Windows\\Defender and class: MSFT_MpComputerStatus but nothing worked.
Below is the code the tool made and even this fails in both my console application and the tool itself.
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\Microsoft\\Windows\\Defender",
"SELECT * FROM MSFT_MpComputerStatus");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSFT_MpComputerStatus instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("AMServiceEnabled: {0}", queryObj["AMServiceEnabled"]);
Console.WriteLine("AntispywareEnabled: {0}", queryObj["AntispywareEnabled"]);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
This should return some bool values indicating whether the services are on or off but once it reaches the foreach loop this exception is thrown "System.Management.ManagementException: This method is not implemented in any class".
Am i missing something here? Is there some other way to get information i need using WMI?
Edit:
After some more searching i also found that MSFT_MpComputerStatusalso exists in the root\\Microsoft\\protectionManagement, but using this namespace produces the same result.
Edit 2:
It is a settings problem. Tested the above code on 3 company development pc's and one non development pc, and the code worked fine on the non development pc. If i find what is the culprit is will post it here.
Edit 3:
It is our anti virus system (bitdefender) that is the root of the problem. Working on finding a workaround, if any.
Edit 4:
See my own anwser.
When windows defender is completely disabled (which most AV software seem to do when it is installed) access to that class is lost but it is still visible. To get the status of windows security in general other methods must be used, such as the SecurityCenter2 namespace (not officially supported), the wscapi (c++) or through some powershell commands.
Our company uses Cisco telephony. And we have a little program on user-s PC wrote by our partner. This program tracks incoming calls and for the call rises record in our CRM-System. This program uses tapi3 (it is COM-object from deep inside of windows). Unfortunately, it doesn't work on PC with Windows 10.
Search a lot for causes of this problem didn't give me even some a bit useful answers. And indeed, I am coming to the opinion, that this library by itself have some problems with working with it on Windows 10.
Well I tried a lot of things, before wrote this question. Tried to use other versions (later versions) of tapi driver for cisco (CiscoTSP). Tried to use other instances of tapi3. Tried to make this program work on other machines with win10. And now I have no result.
This small example demos the problem.
using System;
using System.Collections.Generic;
using TAPI3Lib;
namespace TestTAPI
{
class Program
{
static void Main(string[] args)
{
var tapi = new TAPIClass();
tapi.Initialize();
List<String> names = new List<string>();
foreach (dynamic address in (tapi.Addresses as ITCollection))
{
names.Add(address.AddressName);
}
}
}
}
In result of execution I have empty List of Addresses, but it shouldn't be empty.
At least I should be see standard tapi Addresses, but I didn't. Moreover I see in "Control Panel" -> "Telephone and modem", that I have more Addresses then only standards.
Really don't know what is going wrong. Maybe I miss some details?
Or may be I can change using tapi3 to something else to make that work.
Assuming it works on an Win8 or Win8.1 (you did not specify). Have you checked your drivers config? If you save a config setting and then open the config page in "phone and modem" has it reset to default?
TAPI drivers default registry key for storing their config is here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony
Some (not all) flavors/edition/versions of Windows 10 have removed the access rights to the registry key from the built-in system account that runs the telephony service.
I don't know about Cisco specifically, but we have encountered several TAPI drivers from various manufactures that "save" their settings without giving an error, but in fact have not changed because of this issue.
Open your services.msc and check the Telephony (TapiSrv) service account, then check if it has access to the registry key.
I have a virtual machine with Active Directory that I want to connect to using .NET, I've already connected to an ubuntu machine running OpenLDAP but when connecting to AD it's not working smoothly.
The code I'm attempting to connect with is as follows:
var directoryEntry =
new DirectoryEntry("LDAP://192.168.1.1", #"EXAMPLE\Administrator", "Abc1234");
try
{
var test = directoryEntry.NativeObject;
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
Watching the locals window the variable directoryEntry's Guid, name etc says "Function evaluation timed out".
Then when it arrives at the try block it simply says "The server is not operational".
I've also tried this code, and it fails at the "ldap.bind" telling me that "the ldap-server is unavailable".
using (var ldap = new LdapConnection("192.168.1.1:389"))
{
ldap.AuthType = AuthType.Basic;
ldap.SessionOptions.ProtocolVersion = 3;
ldap.Bind(new NetworkCredential(#"EXAMPLE\Administrator", "Abc1234"));
}
I know the server is up and running, I know that they have a connection (machines can ping each other) but I can't figure out why it isn't working. Can any of you see if there are any flaws in the code? (and yes I've googled all of the errors and various questions about connecting to AD before asking this question but none of the solutions have worked).
If you domain name is 'example.com' and let say you have an organization unit (OU) called 'users'. This works perfectly fine for me.
However the machine where this code runs, is added to the AD domain and it runs with an AD user account. If you do not have a machine added to the same domain which you are querying, you may try "Run as" option (Shift + Right Click) to launch the program or visual studio.
public static List<string> GetAllUsers()
{
List<string> users = new List<string>();
using (DirectoryEntry de = new DirectoryEntry("LDAP://OU=Users,DC=example,DC=local"))
{
using (DirectorySearcher ds = new DirectorySearcher(de))
{
ds.Filter = "objectClass=user";
SearchResultCollection src = ds.FindAll();
foreach (SearchResult sr in src)
{
using (DirectoryEntry user = new DirectoryEntry(sr.Path))
{
users.Add(new string(user.Properties["sAMAccountName"][0].ToString()));
}
}
}
}
return users;
}
I tested your code (with changed domain / password...) in my own Active Directory test environment, it works. If I use a wrong password intentionally for testing purpose, I get "invalid credentials". Fine.
"The server is not operational" will be returned if LDAP is completely unavailable. So it seems that e.g. port 389 is not reachable.
Firewall ?
LDAP SSL (port 636) ??
If you do not have a machine added to the same domain which you are querying, you may try "Run as" option (Shift + Right Click) to launch the program or visual studio.
Yes, this was my first idea too as I saw this question. However, it seems that you will get another error in this case.
What I suggest: install WireShark, the network analyzer and check what is sent over the wire (assuming your AD is running on another machine).
WireShark helped me more than often to diagnose errors with AD, login, SMB or other protocols.
PS:
The answer from Ravi M Patel is a nice example of searching, I almost do the same in my own code.
Problem solved. I had two network adapters and adapter 1 had dhcp and the static ip I was attempting to connect was running on adapter 2. I simply gave adapter 1 the static adress and was able to connect that way, seemingly the code connects via adapter 1 per default. And Thanks for all the answers guys :)
I'm using Microsoft Visual Studio to make a simple remote task manager for experience purposes.
I want to use Process.GetProcesses(string); but there is an access denied exception that won't allow me to get the remote computer process. In fact it is normal because we should authenticate using a user name and password, but how?
You may try to use WMI for this purpose
/// using System.Management;
// don't forget! in VS you may have to add a new reference to this DLL
ConnectionOptions op = new ConnectionOptions();
op.Username = "REMOTE_USER";
op.Password = "REMOTE_PASSWORD";
ManagementScope sc = new ManagementScope(#"\\REMOTE_COMPUTER_NAME\root\cimv2", op);
ObjectQuery query = new ObjectQuery("Select * from Win32_Process");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(sc, query);
ManagementObjectCollection result = searcher.Get();
foreach (ManagementObject obj in result)
{
if (obj["Caption"] != null) Console.Write(obj["Caption"].ToString() + "\t");
if (obj["CommandLine"] != null) Console.WriteLine(obj["CommandLine"].ToString());
}
For further details on Win32_Process class see MSDN.
hth
EDIT: Just read your post again, the steps described in my post only apply in a domain, I assume you work inside a workgroup. I'm sorry.
I recently ran into a similar issue when running Visual Studio as Administrator on Windows 7. It seems like permissions on remote machines and network shares are dropped (even in a domain!) if you elevate your program to run as local administrator, which will be the case if you run a program out of VS when VS is run as admin. This even happens if you have domain wide admin accounts.
Try the following:
Build the solution
Run it manually with your account which has hopefully
privileges on the remote computer from windows explorer, without elevation
If this helps, you could stop running VS as administrator. It worked out for me.
I'm pretty sure you need elevation to do this, or at least use a stronger user by impersonation
I'm using WMI inside c# to get a list of users currently "logged in" to a machine:
ManagementScope ms = new ManagementScope(ManagementPath.DefaultPath);
var q = new SelectQuery("Win32_LoggedOnUser");
using (var query = new ManagementObjectSearcher(ms, q)) {
using (var results = query.Get()) {
foreach (var r in results) {
using (var o = new ManagementObject(r["Dependent"].ToString())) {
var logonType = o["LogonType"];
if (logonType == "2") {
// Interactive user is logged in, retrieve the name
using (var userObj = new ManagementObject(r["Antecedent"].ToString())) {
name = userObj["Name"].ToString();
}
}
...
This works great, but it seems that in some cases even after the user logs out, WMI still reports it as being logged in. One particular case is when that user accesses a network share during the session.
Is there anyway around this? Perhaps a way to test a session to see if it was created as a share or if it's active?
Any tips would be greatly appreciated.
Even though the user has logged off, because you accessed another computer's files remotely, the connection remains open for a period of time.
https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states
Look under Run > cmd > netstat -a. You should see a connection called microsoft-ds after you have established a connection through Windows Explorer to another computer. This is the service that Microsoft uses for file transfers, among other things. If you see a TIME_WAIT or CLOSE_WAIT, the connection is still open even if window you used to access the files is closed.
You can check this programmatically by using "handle.exe", a tool provided by Microsoft that is a part of Sysinternals, that will be able to provide information on which part of the hive is still active. This should include Registry Keys, ports, the works.
http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx
WMI may be reporting that the user is still logged in because a port or connection has not been closed that was initiated by that user. This type of thing has caused us a few headaches, so we use handle.exe to dump anything keeping the hive open for a user and then systematically kill/close all of it before we do any profile maintenance (as an automation).
Of course, rebooting the computer always works. =)