Friday, 31 July 2015

Difference between single and double quotes in Powershell

You might have come across the question "What are the differences between single and double quotes in Powershell" when you are working with string manipulation. Both quotes are used to delimit string values. In general, you should use single quotes, unless you are required to replace a string variable with concatenation of two string values (string literal and string variable).

If you put double quotes, inside double quotes, powershell looks for the $ character. If it finds it, it assumes that any following characters up to the next white space are a variable name. It replaces the variable reference with the variable’s contents. Consider the following scenario:
$x = "Hello"
$y = "$x World"
The $y variable will now contain "Hello World" because the double quote concatenates the content of the variable $x with remaining string value. In general, use only single quotes if you don't have the above need.

Create Bulk Mailbox Users from CSV using Powershell

We can use the Exchange Powershell cmdlet New-Mailbox to create mailbox AD user.In this article, I am going write powershell script create bulk exchange mailbox users from csv and enable mailboxes for existing AD users.

Before proceed, run the following command to enable Exchange cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*
The following command creates the Active Directory user "Tim Brensan" in the TestOU, with a mailbox on the "TestDBStore" database and set the "Change Password at Next Logon" flag as true.
New-Mailbox -UserPrincipalName timbrensan@testdomain.com -Alias 'TimBrensan' -Database 'TestDBStore' -Name TimBrensan –OrganizationalUnit TestOU -Password (ConvertTo-SecureString 'MyP@ssw0rd1' -AsPlainText -Force) -FirstName Tim -LastName Brensan -DisplayName 'Tim Brensan' -ResetPasswordOnNextLogon $True

Create Bulk Exchange Mailbox Users from CSV

1. Consider the CSV file MailboxUsers.csv which contains set of new exchange mailboxes to create with the attributes name, alias, userPrincipalName, database, firstName, lastName, displayName and ParentOU.
Create Bulk Mailbox AD Users from CSV file using Powershell
2. Copy the below Powershell script and paste in Notepad file.
3. Change the MailboxUsers.csv file path with your own csv file path.
4. SaveAs the Notepad file with the extension .ps1 like Create-Bulk-Mailbox-AD-Users.ps1
Import-Csv "C:\Scripts\MailboxUsers.csv" | ForEach-Object {
New-Mailbox -UserPrincipalName $_.'userPrincipalName' -Alias $_.'alias' -Database $_.'database' -Name $_.'name' –OrganizationalUnit $_.'ParentOU' -Password (ConvertTo-SecureString 'MyPassword123' -AsPlainText -Force) -FirstName $_.'firstName' -LastName $_.'lastName' -DisplayName $_.'displayName' -ResetPasswordOnNextLogon $True }
5. Now run the file Create-Bulk-Mailbox-AD-Users.ps1 in powershell to create bulk Active Directory users and Mailboxes from CSV file.

Create Bulk Mailboxes for existing AD Users

1. Consider the CSV file ADUsers.CSV which contains set of existing AD users that we want to enable mailbox with the attributes name, alias and database.
Create Mailbox for Bulk AD Users from CSV using Powershell
2. Copy the below Powershell script and paste in Notepad file.
3. Change the ADUsers.CSV file path with your own csv file path.
4. SaveAs the Notepad file with the extension .ps1 like Create-Mailbox-for-Bulk-AD-Users.ps1
Import-Csv "C:\Scripts\ADUsers.csv" | ForEach-Object {
Enable-Mailbox -Identity:$_.'name' -Alias:$_.'alias' -Database:$_.'database'
}
5. Now run the file Create-Mailbox-for-Bulk-AD-Users.ps1 in Powershell to create Bulk Active Directory users and Mailboxes from CSV file.

Thursday, 30 July 2015

How to get Remote Desktop Sessions (RDP) using Powershell

In Powershell, we can get a list of remote desktop sessions (rdp) using the commands QWinsta and Query.

List Remote Desktop Sessions using QWinsta:

QWinsta /server:[Server name or IP]
Replace the parameter [Server name or IP] with the name or IP address of the remote machine.
QWinsta /server:210.168.1.54

Get Remote Desktop Sessions using Query:

Query user /server:[Server name or IP]
Replace the parameter [Server name or IP] with the name or IP address of the remote computer.
Query user /server:210.168.1.54
You can use the below powershell command to get clear output.
(Query user /server:210.168.1.54) -replace '\s{2,}', ',' | ConvertFrom-Csv
The following command exports the output to CSV file.
(Query user /server:210.168.1.54) -replace '\s{2,}', ',' | ConvertFrom-Csv |
Export-CSV "C:\\RDPSessions.csv" -NoTypeInformation -Encoding UTF8 

Tuesday, 28 July 2015

Create Mailbox User using Powershell

Creating new mailbox user is one of the important task for every Administrator either for actual new employee or for internal testing. You can use Exchange Management console to create new mailbox user, but it is a time consuming job if you want to create multiple AD users (bulk mailbox users). To overcome this, we can use Powershell Script to Create new AD User with mailbox.

Before proceed, run the following command to enable Exchange cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*

Summary:

Create New Mailbox User

We can use the Exchange Management Powershell cmdlet New-Mailbox to create new mailbox AD user. The following command creates the Active Directory user "Will Smith" in the TestOU, with a mailbox on the TestDBStore database.
New-Mailbox -UserPrincipalName willsmith@testdomain.com -Alias 'WillSmith' -Database 'TestDBStore' -Name WillSmith –OrganizationalUnit TestOU -Password (ConvertTo-SecureString 'MyPassword123' -AsPlainText -Force) -FirstName Will -LastName Smith -DisplayName 'Will Smith' -ResetPasswordOnNextLogon $True

Enable Mailbox for existing AD User

We can create a mailbox for an existing Active Directory user using exchange powershell cmdlet Enable-Mailbox. The following powershell command creates mailbox for the existing AD user "Chris Jordan".
Enable-Mailbox -Identity:'ChrisJordan' -Alias:'ChrisJordan' -Database: 'TestDBStore'

Create Bulk Mailbox AD Users from CSV file using Powershell

1. Consider the CSV file MailboxUsers.csv which contains set of new mailbox ad users to create with the attributes name, alias, userPrincipalName, database, firstName, lastName, displayName and ParentOU.
Create Bulk Mailbox AD Users from CSV file using Powershell
2. Copy the below Powershell script and paste in Notepad file.
3. Change the MailboxUsers.csv file path with your own csv file path.
4. SaveAs the Notepad file with the extension .ps1 like Create-Bulk-Mailbox-AD-Users.ps1
Import-Csv "C:\Scripts\MailboxUsers.csv" | ForEach-Object {
New-Mailbox -UserPrincipalName $_.'userPrincipalName' -Alias $_.'alias' -Database $_.'database' -Name $_.'name' –OrganizationalUnit $_.'ParentOU' -Password (ConvertTo-SecureString 'MyPassword123' -AsPlainText -Force) -FirstName $_.'firstName' -LastName $_.'lastName' -DisplayName $_.'displayName' -ResetPasswordOnNextLogon $True }
5. Now run the file Create-Bulk-Mailbox-AD-Users.ps1 in Powershell to create Bulk Active Directory users and Mailboxes from CSV file.

Enable Mailbox for Bulk AD Users from CSV using Powershell

1. Consider the CSV file ADUsers.CSV which contains set of existing AD users that we want to enable mailbox with the attributes name, alias and database.
Create Mailbox for Bulk AD Users from CSV using Powershell
2. Copy the below Powershell script and paste in Notepad file.
3. Change the ADUsers.CSV file path with your own csv file path.
4. SaveAs the Notepad file with the extension .ps1 like Create-Mailbox-for-Bulk-AD-Users.ps1
Import-Csv "C:\Scripts\ADUsers.csv" | ForEach-Object {
Enable-Mailbox -Identity:$_.'name' -Alias:$_.'alias' -Database:$_.'database'
}
5. Now run the file Create-Mailbox-for-Bulk-AD-Users.ps1 in Powershell to create Bulk Active Directory users and Mailboxes from CSV file.

GPO : Default Group Policies and Settings

By default, the group policy objects Default Domain Policy and the Default Domain Controllers Policy are created when we create a new Active Directory domain.

Default Domain Policy:

The default domain policy includes the following three security polices. You can check these policies under Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies.
  • Password Policy 
  • Account Lockout Policy 
  • Kerberos Policy.
These three policies can only be set at the Domain level. If you configure these settings anywhere else -in Site or OU, they are ignored. However, setting these three policies at the OU level will have the effect if users log on locally to their PCs. Login to the domain you get the domain policy, login locally you get the OU policy.

The default domain policy also includes the following three security options. You can check these settings under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options.
  • Automatically log off users when logon time expires 
  • Rename Adminsitrator Account - When set at the domain level, it affects the Domain Administrator account only. 
  • Rename Guest Account - When set at the domain level, it affects the Domain Guest account only.
For the above listed policies, you can use only the Default Domain Policy.

Default Domain Controllers Policy:

This policy can be found by right clicking the Domain Controllers OU. This policy affects all Domain Controllers in the domain regardless of where you placed the domain controllers. That means, you can put your domain controllers in any container (OU) in Active Directory (other than Domain Controllers OU), the outside domain controllers also process this policy and get settings from this policy.

Use the Default Domain Controllers Policy to set local policies for your domain controllers, e.g. Audit Policies, Event Log settings.

How to Apply Group Policy at OU Level

GPOs can be configured Locally, at the Site level, the Domain level or at the Organizational Unit (OU) level. Group Policies are applied in a Specific Order, LSDOU. This order means that the local GPO is processed first, and GPOs that are linked to the Organizational Unit are processed last, so the OU level GPO overwrites settings in the earlier GPOs if there are conflicts.

As OU policies are applied starting at the "root level", we can organize users and computers into different containers and apply GPO to a specific OU depends on various organization needs. We can set a Group Policy to OU by following two ways:

    - Create a new GPO and Link it to OU
    - Link an existing GPO to OU

Create a new GPO and Link it to a Organizational Unit (OU)

1. Open the Group Policy Management console by running the command gpmc.msc.

2. Expand the tree Forest >> Domains , right-click on the OU where you want to apply new policy, click Create a GPO in this domain, and Link it here...

How to Apply Group Policy at OU Level

3. Type the new policy name and click OK and you can edit GPO settings by right-click on the newly created GPO and click Edit.

Friday, 24 July 2015

Enable ActiveSync for Mailbox Users using Powershell

We can enable and disable Exchange ActiveSync feature for mailbox users using the powershell cmdlet Set-CASMailbox. This article contains Powershell scirpt to enable ActiveSync feature for a single user and set of users.

Before proceed, run the following command to enable Exchange cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*

Enable Exchange ActiveSync for a Single User:

Run the following command to enable Exchange ActiveSync for a single user:
Set-CASMailbox -Identity "Morgan" -ActiveSyncEnabled $True
Use the below command and check the ActiveSync feature is enabled for the corresponding user which you have used in the above command.
Get-CASMailbox -ResultSize Unlimited

Enable ActiveSync Feature for a Group of Users:

We can use the Active Directory powershell cmdlet Get-ADUser to get a group of users and pass the selected users to Set-CASMailbox cmdlet to enable Exchange ActiveSync feature. We can set target OU and apply filter in Get-ADUser cmdlet to get specific set of users. Before proceed, run the following command to import Active Directory powershell cmdlets.
Import-Module ActiveDirectory
The following powershell command select and enable ActiveSync feature for all the users from the container TestOU.
$users = Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=com";
$users | ForEach-Object {
Set-CASMailbox -Identity $_.Name -ActiveSyncEnabled $True
}
You can also apply Filter to select particular set of users, the following command select and enable Exchange ActiveSync feature for all the users who are under Testing department.
$users = Get-ADUser -Filter 'Department -like "*Testing*"';
$users | ForEach-Object {
Set-CASMailbox -Identity $_.Name -ActiveSyncEnabled $True
}
Instead of SQL like fiter, you can use ldap filter by using the parameter -LDAPFilter.
$users = Get-ADUser -LDAPFilter '(Department=*Testing*)';
$users | ForEach-Object {
Set-CASMailbox -Identity $_.Name -ActiveSyncEnabled $True
}

Enable ActiveSync Feature for Multiple Users:

Use the below powershell script to enable Exchange ActiveSync connectivity for a set of mailbox users. Give the set of user names as string Array.
$users = "usr1","usr2","usr3","usr4"
Foreach($user in $users) {
Set-CASMailbox -Identity $user -ActiveSyncEnabled $True
}

List Users with ActiveSync Disabled using Powershell

We can find and list users with ActiveSync disabled using the Powershell cmdlet Get-CASMailbox. This article contains Powershell script to get a list of ActiveSync disabled mailbox users and export user details to CSV file.

Before proceed, run the following command to enable Exchange Powershell cmdlets if you are working with normal Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*

List Exchange ActiveSync Disabled Users:

The Get-CASMailbox cmdlet returns the status of mailbox features (OWA, Exchange ActiveSync, POP3, and IMAP4) for all users, we can use Where-Object and filter only users with Exchange ActiveSync disabled.
Get-CASMailbox -ResultSize Unlimited | Where-Object { $_.ActiveSyncEnabled -eq $false}
You can get users from specific container (OU) by adding the parameter OrganizationalUnit.
$OU='OU=TestOU,DC=TestDomain,DC=com'
Get-CASMailbox -OrganizationalUnit $OU -ResultSize Unlimited |
Where-Object { $_.ActiveSyncEnabled -eq $false}

Export ActiveSync Disabled Users to CSV:

The following powershell script exports Exchange ActiveSync disbaled users to CSV file.
Get-CASMailbox -ResultSize Unlimited | Where-Object { $_.ActiveSyncEnabled -eq $false} |
Select Name,ActiveSyncEnabled,OWAEnabled |
Export-CSV "C:\\ActiveSyncDisabledUsers.csv" -NoTypeInformation -Encoding UTF8

Thursday, 23 July 2015

How to enable or disable Ping service in Windows 2008/2012 R2

Ping is used to check if a remote machine is online or offline. It is a small network packet sent to the machine. If the machine is up, an answer will be sent. This can be used to scan an IP-range for reachable hosts for potential hackers. For security reason, you might needed to disable this ping service.

Stepts to Disable Ping Service:

1. Go to Start -> Administrative Tools -> Windows Firewall with Advanced Security -> Inbound Rules -> File and Printer Sharing (Echo Request – ICMPv4-IN).
2. Right-click on the rule File and Printer Sharing (Echo Request – ICMPv4-IN) and select Enable Rule.
3. Now, right-click on the same rule and click Properties.
4. In General tab, under the section Action, select the option Block the connection and click Apply button.

How to enable or disable Ping Service in Windows 2008/2012 R2

Thats all, you can try a ping command from other remote machine and you could see the response as "Request timed out".

Enable Ping Service:

To enable ping service, you can either disable the rule File and Printer Sharing (Echo Request – ICMPv4-IN) or select the Action Allow the connection.

C# : Check If Machine is Online or Offline

In C#, We can test if a remote computer is online or offline using Ping service. For security reason, the Ping service may be disabled in your network, in that case, you can use WMI service to check if a remote computer is up or down.

Summary:


C# - Check If Machine is Up or Down using Ping Service

You can use the C# class Ping from System.Net.NetworkInformation namespace to find a remote machine is alive or not. This is the fastest way to check a remote machine online status compared with using WMI Service method.
// using System.Net.NetworkInformation;
private static bool IsMachineUp(string hostName)
{
    bool retVal = false;
    try
    {
        Ping pingSender = new Ping();
        PingOptions options = new PingOptions();
        // Use the default Ttl value which is 128,
        // but change the fragmentation behavior.
        options.DontFragment = true;
        // Create a buffer of 32 bytes of data to be transmitted.
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes(data);
        int timeout = 120;

        PingReply reply = pingSender.Send(hostName, timeout, buffer, options);
        if (reply.Status == IPStatus.Success)
        {
            retVal = true;
        }
    }
    catch (Exception ex)
    {
        retVal = false;
        Console.WriteLine(ex.Message);
    }
    return retVal;
}

C# - Check If Machine is Online or Offline using WMI (without Ping Service)

You can use Ping service to get faster results, but for security reason, the Ping service may be disabled in your network, in that case, you can use WMI service in C# to find a remote host is up or down.
// using System.Management;
private static bool IsMachineOnline(string hostName)
{
    bool retVal = false;
    ManagementScope scope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", hostName));
    ManagementClass os = new ManagementClass(scope, new ManagementPath("Win32_OperatingSystem"), null);
    try
    {
        ManagementObjectCollection instances = os.GetInstances();
        retVal = true;
    }
    catch (Exception ex)
    {
        retVal = false;
        Console.WriteLine(ex.Message);
    }
    return retVal;
}

Wednesday, 22 July 2015

Powershell - Declare Array and Iterate with ForEach

In Powershell, you can iterate through list of objects (or collection of objects) using ForEach loop. You can either initialize new array variable or get collection of objects from other cmdlet and store it in an array variable and iterate the array object using foreach loop function. You can also iterate collection of objects using ForEach-Object cmdlet.

Let's declare array variable with list of string values:
$strArray = @("value1", "value2", "value3","value4")
Now, we can pass this array object to ForEach statement and get all the elements one-by-one and process it.
$strArray = @("value1", "value2", "value3","value4")
ForEach($str in $strArray) 
{
        Write-Host  "Processing the string element:" $str
}
You can also process the list of objects using ForEach-Object cmdlet.
$strArray = @("value1", "value2", "value3","value4")
$strArray | ForEach-Object {
        Write-Host  "Processing the string element:" $_
}
Although we can use both ForEach statement and ForEach-Object to return the same results, there are some differences between them regarding performance and usage. We can pass the output of ForEach-Object to next pipeline, but we can’t do this with foreach statement. The ForEach-Object cmdlet process each element as it passes through the pipeline, so it uses less memory, but foreach statement generates the entire collection before processing individual values.

Tuesday, 21 July 2015

Disable ActiveSync for Mailbox Users using Powershell

We can enable and disable Exchange ActiveSync feature for mailbox users using Set-CASMailbox cmdlet. In this article, I am going write Powershell scirpt to disable ActiveSync feature for a single user and disable ActiveSync feature for a set of users.

Before proceed, run the following command to enable Exchange cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*

Disable Exchange ActiveSync for a Single User:

Run the following command to disable Exchange ActiveSync for a single user:
Set-CASMailbox -Identity "Morgan" -ActiveSyncEnabled $False
Run the below command and check the ActiveSync feature is disabled or not for the corresponding user which you have used in the above command.
Get-CASMailbox -ResultSize Unlimited

Disable ActiveSync Feature for a Group of Users:

We can use the Active Directory powershell cmdlet Get-ADUser to get a group of users and pass the selected users to Set-CASMailbox cmdlet to disable ActiveSync feature. We can set target OU and apply filter in Get-ADUser cmdlet to get specific set of users. Before proceed, run the following command to import Active Directory powershell cmdlets.
Import-Module ActiveDirectory
The following powershell command select and disable ActiveSync feature for all the users from the container TestOU.
$users = Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=com";
$users | ForEach-Object {
Set-CASMailbox -Identity $_.Name -ActiveSyncEnabled $False
}
The following command select and disable Exchange ActiveSync feature for all the users who are under Testing department.
$users = Get-ADUser -Filter 'Department -like "*Testing*"';
$users | ForEach-Object {
Set-CASMailbox -Identity $_.Name -ActiveSyncEnabled $False
}

Disable ActiveSync Feature for Multiple Users:

Use the below powershell script to disable Exchange ActiveSync connectivity for a set of mailbox users. Give the set of user names as string Array.
$users = "usr1","usr2","usr3","usr4"
Foreach($user in $users) {
Set-CASMailbox -Identity $user -ActiveSyncEnabled $False
}

How to Logoff Remote Desktop User via Command Line

We can logoff a remote desktop user session by using the command line tool Logoff.

Logoff command syntax:

LOGOFF [sessionname | sessionid] [/SERVER:servername] [/V] [/VM]

  sessionname         The name of the session.
  sessionid           The ID of the session.
  /SERVER:servername  Specifies the Remote Desktop server containing the user session to log off.
  /V                  Displays information about the actions performed.
  /VM                 Logs off a session on server or within virtual machine.
Before proceed, we should find the ID of the session which we want to terminate, we can list all the remote desktop user sessions by using the command QWinsta.
QWinsta /server:[Server name or IP]
Replace the parameter [Server name or IP] with the name or IP address of the Remote Computer. You will get the list of remote user sessions with username and session ids in the command window.
How to Logoff Remote Desktop User via Command Line

From the above output you can easily find the session id of an user whom you want to logoff. Now, I am trying to terminate the user Administrator and its session id is 1.

Command to logoff remote user:

Logoff /SERVER:[Server name or IP] [Session ID] /V 
Example:
Logoff /SERVER:202.68.1.51 1 /V 

Command to disconnect remote user:

You can also use the following command if you want only disconnect the remote user session instead of complete logoff.
RWinsta /server:[Server name or IP] [Session ID]
Example:
RWinsta /server:202.68.1.51 1
Finally, use the command QWinsta to confirm the user is logged out/disconnected successfully.
QWinsta /server:202.68.1.51

Monday, 20 July 2015

List and Disconnect Remote Desktop Sessions via Command Line

We can list all the Remote Desktop sessions by using the command line tool QWinsta and we can disconnect RDP Sessions using the command RWinsta.
QWinsta /server:<Server name or IP>
Replace the parameter <Server name or IP> with the name or IP address of the Remote Computer.

Example:

QWinsta /server:202.68.1.51
You will get a list of Remote Sessions with username and session ids in the command window.
List and Disconnect Remote Desktop Sessions via Command Line
From the above output you can easily find what are the RDP sessions are Active from the field STATE. In order to disconnect a user, first, we should find the session id for the corresponding user and you can the session id for the user Administrator is 1.

Use the following command to disconnect the remote session:
RWinsta /server:<Server name or IP> <Session ID>
I have used the below command to terminate the session of the Administrator:
RWinsta /server:202.68.1.51 1
Once again use the command QWinsta to confirm the user is disconnected successfully.
QWinsta /server:202.68.1.51
Now, you can see the Administrator is not listed in available RDP sessions.
C:\> QWinsta /server:202.68.1.51

 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
 services                                    0  Disc
 rdp-tcp                                 65536  Listen

Get ActiveSync Enabled Mailboxes using Powershell

We can get and list Exchange ActiveSync enabled mailboxes using the Powershell cmdlet Get-CASMailbox. In this article, I am going write Powershell script to get a list of ActiveSync Enabled Mailbox Users and Export ActiveSync Enabled User details to CSV file.

Before proceed, run the following command to enable Exchange Powershell cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*

List Exchange ActiveSync enabled mailboxes:

The Get-CASMailbox cmdlet returns all the features for all the mailboxes users, we can use Where-Object and filter only users with Exchange ActiveSync Enabled.
Get-CASMailbox -ResultSize Unlimited | Where-Object { $_.ActiveSyncEnabled -eq $true}
You can add the parameter OrganizationalUnit if you want to list users from specific container (OU).
$OU='OU=TestOU,DC=TestDomain,DC=com'
Get-CASMailbox -OrganizationalUnit $OU -ResultSize Unlimited |
Where-Object {$_.ActiveSyncEnabled -eq $true}

Export ActiveSync Enabled mailboxes to CSV:

The following powershell script exports all the ActiveSync enabled mailbox users to CSV file.
Get-CASMailbox -ResultSize Unlimited | Where-Object { $_.ActiveSyncEnabled -eq $true} |
Select Name,ActiveSyncEnabled,OWAEnabled |
Export-CSV "C:\\ActiveSyncEnabledUsers.csv" -NoTypeInformation -Encoding UTF8

Thursday, 16 July 2015

C# : The server is unwilling to process the request

Problem:

I am receiving the error "The server is unwilling to process the request" when changing the AD attribute userAccountControl to enable user account in C#. I am using the below C# code to enable AD user account and reset password.
public static void EnableADUser(string username)
{
    DirectoryEntry user = new DirectoryEntry("LDAP://CN="+username+ ",OU=TestOU,DC=TestDomain,DC=com");
    int old_UAC = (int)user.Properties["userAccountControl"][0];

    // Enable User Account
    user.Properties["userAccountControl"][0] = (old_UAC & ~2);
    user.CommitChanges();

    // Reset Password
    user.Invoke("SetPassword", new object[] { "MyP@$$w0rd" });
    user.CommitChanges();
}

Cause:

The cause of the problem is, we are modifying new user attribute before Set the Password. So, we should set the password for new user before making any attribute change. I have changed my C# code to reset password first and change attribute.
public static void EnableADUser(string username)
{
    DirectoryEntry user = new DirectoryEntry("LDAP://CN="+username+ ",OU=TestOU,DC=TestDomain,DC=com");

    // Reset Password
    user.Invoke("SetPassword", new object[] { "MyP@$$w0rd" });
    user.CommitChanges();

    int old_UAC = (int)user.Properties["userAccountControl"][0];
    // Enable User Account
    user.Properties["userAccountControl"][0] = (old_UAC & ~2);
    user.CommitChanges();
}

Powershell : List only required Parameters for a Cmdlet

We can get all the required parameters for a Powershell cmdlet using Get-Help cmdlet. The Get-Help displays the detailed description of all the available parameters if we pass the parameter -Parameter * and we can filter the results using Required property to get only required parameters for a powershell cmdlet.

The following command displays all the available parameters of the Get-Childitem cmdlet.
Get-Help Get-ChildItem -Parameter *
To view only the required parameters, we can filter the results using Where-Object with Required property.:
Get-Help Get-ChildItem -Parameter * | Where-Object {$_.Required -eq $true}

Powershell : List all the available Parameters for a Cmdlet

We can get all the available parameters for a Powershell cmdlet using Get-Help cmdlet, it displays the detailed description of all the available parameters.
Get-Help [Cmdlet Name] -Parameter *
The following command displays descriptions of all the parameters of the Get-Childitem cmdlet.
Get-Help Get-ChildItem -Parameter *
The following command displays descriptions of the parameters of the Get-Childitem cmdlet that begin with "F" (Filter and Force):
Get-Help Get-ChildItem -Parameter F*

Powershell : Check if AD User is Member of a Group

We can find if an Active Directory user is member of an AD group using Get-ADGroupMember cmdlet. In this article, I am going to write powershell script to check if user is exists in a group or nested group, and check multiple users are member of an AD group.

Run the following command to import Active Directory cmdlets.
Import-Module ActiveDirectory

Powershell scipt to check if User is Member of a Group:

The following powershell script checks whether the given user is member of the given group. We are using the parameter -Recursive with Get-ADGroupMember cmdlet to get nested group members along with direct group members.
$user = "TestUser"
$group = "Domain Admins"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty Name

If ($members -contains $user) {
      Write-Host "$user exists in the group"
 } Else {
        Write-Host "$user not exists in the group"
}

Check if multiple users are member of a Group:

Use the below powershell command to check if multiple users are member of a Group.
$users = "TestUser1","TestUser2"
$group = "Domain Admins"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty Name
ForEach ($user in $users) {
    If ($members -contains $user) {
      Write-Host "$user exists in the group"
 } Else {
      Write-Host "$user not exists in the group"
}}

Check if User is member of AD Group using VBScript

In this article, I am going to write vbscript code to find an Active Directory user is member of an AD group. We can check it by getting user object using GetObject function with ADSI WinNT provider and gets group list from the user object.

VBScript check if user is member of domain group

1. Copy the below example vbscript code and paste it in notepad or a VBScript editor.
2. Save the file with a .vbs extension, for example: CheckMembership.vbs.
3. Replace the domainName,userName and groupName with your own values.
4. Double-click the vbscript file (or Run this file from command window) to check if a user exists in AD group or not.
Option Explicit
Dim domainName,userName,groupName,ADSPath,grouplistD
Dim objUser,objGroup

domainName = "TestDomain.com"
userName = "Morgan"
groupName = "Domain Admins"

If IsMember(domainName,userName,groupName) Then
    Wscript.echo "The user '"&userName&"' exists in the group '"&groupName&"'"
 Else
    Wscript.echo "The user '"&userName&"' not exists in the group '"&groupName&"'"
End If
WScript.quit
 
' *****************************************************
'This function checks if the given AD user is member of the given group.
Function IsMember(domainName,userName,groupName)
   Set groupListD = CreateObject("Scripting.Dictionary")
   groupListD.CompareMode = 1
   ADSPath = domainName & "/" & userName
   Set objUser = GetObject("WinNT://" & ADSPath & ",user")
   For Each objGroup in objUser.Groups
      groupListD.Add objGroup.Name, "-"
   Next
   IsMember = CBool(groupListD.Exists(groupName))
End Function
' *****************************************************

Wednesday, 15 July 2015

VBScript: How to Create and Write text in CSV file

You might have come across the need of export text content to CSV file in vbscript. We can create and write text content into CSV file using FileSystemObject. The CSV is nothing but the comma-separated-values, a text file in which individual values are separated by commas (,).

Create and Write text content to csv file includes following steps:

- Create new text file with .csv extention using CreateTextFile function.
- Write colunm headers as comma-separated-values in first line of the text file.
- Write data as comma-separated-values line-by-line.
- We use WriteLine method to move next line in text file, which is equivalent to hitting ENTER on the keyboard.
Dim csvFilePath,csvColumns
Const ForWriting = 2

' Create new CSV file 
csvFilePath ="C:\TestExport.csv"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objCSVFile = objFSO.CreateTextFile(csvFilePath, _ 
    ForWriting, True)

' Write comma delimited list of columns in new CSV file.
csvColumns = "Col1,Col2,Col3"
objCSVFile.Write csvColumns
objCSVFile.Writeline

' Write test values as comma-separated in new CSV file.
 For i = 0 to 5 
    objCSVFile.Write chr(34) & "Value1" & chr(34) & ","
    objCSVFile.Write chr(34) & "Value2" & chr(34) & ","
    objCSVFile.Write chr(34) & "Value3" & chr(34) & ""
    objCSVFile.Writeline
 Next
The symbol chr(34) is nothing but double quote ("), which is used to surround your fields with double quotes to preserve csv special characters.

Note: Since we are creating the text file with .csv extension instead of actual csv file, if you open the csv file using MS Excel, the line should comes in a single cell, to fix this issue, copy the content of the csv file and paste in new text file and save it as new .csv file.

Get Exchange Mailbox Features using Powershell

We can use the Exchange Powershell cmdlet Get-CASMailbox to get all the mailbox features, it returns whether the mailbox features (OWA, Exchange ActiveSync, POP3, and IMAP4) are enabled or disabled.

Before proceed, run the following command to enable Exchange cmdlets if you are working with Powershell console instead of Exchange Management Shell.
Add-PSSnapin *Exchange*
The below command gets all the features for all mailboxes.
Get-CASMailbox -ResultSize Unlimited
You can add the parameter Identity if you want to get a single user's mailbox feature.
Get-CASMailbox -Identity "Morgan"
You can add the parameter OrganizationalUnit if you want to get the features of a users from specific container (OU).
$OU='OU=TestOU,DC=TestDomain,DC=com'
Get-CASMailbox -OrganizationalUnit $OU -ResultSize Unlimited
By default, it returns all the features, you can use Select command if you want to get only selected features list.
Get-CASMailbox -ResultSize Unlimited | Select Name,ActiveSyncEnabled,OWAEnabled

List Mailbox Users with ActiveSync Enabled:

Use the following command to list only ActiveSync feature enabled users.
Get-CASMailbox -ResultSize Unlimited | Where { $_.ActiveSyncEnabled -eq 'True'}
Like this, you can also filter with other features. The below command lists only users with OWA Enabled.
Get-CASMailbox -ResultSize Unlimited | Where { $_.OWAEnabled -eq 'True'}

Export All User's Mailbox Features to CSV:

Use the below powershell script to export mailbox features of all users to CSV file.
Get-CASMailbox -ResultSize Unlimited |
Select Name,ActiveSyncEnabled,OWAEnabled,PopEnabled,ImapEnabled,MapiEnabled |
Export-CSV "C:\\MailBoxFeatures.csv" -NoTypeInformation -Encoding UTF8
The following script exports only users with ActiveSync Enabled
Get-CASMailbox -ResultSize Unlimited | Where { $_.ActiveSyncEnabled -eq 'True'} |
Select Name,ActiveSyncEnabled,OWAEnabled |
Export-CSV "C:\\ActiveSyncEnabledUsers.csv" -NoTypeInformation -Encoding UTF8

Tuesday, 14 July 2015

PowerShell : Check if Machine is Up or Down

In this article, I am going write Powershell script to check if a given computer is up (online) or down (offline) and script to check ping status of set of remote machines (from text file-txt) and export its output to CSV file.

PowerShell script to find if a Machine is Online or Offline:

We can use the powrshell cmdlet Test-Connection to send a ping command to remote computer to check whether the remote machine is up or down. We can pass the parameter –Quiet to returns only True or False instead of test connection failed error.
$remoteComputer = "hp-PC"
IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $remoteComputer -Quiet) {
        Write-Host "The remote machine is Online"
} Else {
        Write-Host "The remote machine is Down"
}

Check Ping status for set of Remote Computers:

Use the below powershell script to test connectivity for set of remote computers. Give the set of machine names as string Array.
$computers = "pc1","pc2","svr1","hp-pc"
Foreach($c in $computers) {
IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $c -Quiet) {
        Write-Host "The remote computer " $c " is Online"
} Else {
        Write-Host "The remote computer " $c " is Offline"
}}

Export Ping status of set of Computers to CSV file:

Use the below powershell script to find ping status for multiple remote computers. First create the text file RemoteComputers.txt which includes one machine name in each line. You will get the hostname and its ping status in the CSV file PingStatus.csv.
Get-Content C:\RemoteComputers.txt | ForEach-Object{
$pingstatus = ""
IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $_ -Quiet) {
        $pingstatus = "Online"
} Else {
        $pingstatus = "Offline"
}

New-Object -TypeName PSObject -Property @{
      Computer = $_
      Status = $pingstatus }
} | Export-Csv C:\PingStatus.csv -NoTypeInformation -Encoding UTF8

Monday, 13 July 2015

VBScript: Invalid Character 800A0408 compilation error in Line 1 Char 1

Problem:

I am receiving the vbscript error "Invalid Character 800A0408 compilation error at Line 1 Char 1" while running a vbscript file which contains following code (this is just a sample code).
Option Explicit
Dim strUser
strUser = "Morgan"
WScript.Echo "Hello ! " & strUser 
Wscript.Quit
I have received below error:
Script: C:\Test.vbs
Line: 1
Char: 1
Error: Invalid character
Code: 800A0408
Source: Microsoft VBScript compilation error

Fix/Solution:

This issue was occurs due to the Encoding method UTF-8 which I used to save the .vbs file. We should use the Encoding method ANSI to save .vbs file. Follow the below steps to fix this issue:

    1. Open the vbscript file in Notepad
    2. Go to File and click "Save as"
    3. Under the file name, you will see a drop down menu for Encoding. Choose ANSI.
    4. Save the file.

VBScript Invalid Character 800A0408 compilation error at Line 1 Char 1


VBScript Resolve IP Address to Hostname

In this article, I am going write vbscript code to resolve computer name from IP address and vbscript code to get hostname of multiple IP addresses (from text file) and export its output to CSV file.

Resolve IP Address to Hostname:

The below vbscript code resolves the computer name from given IP address.
Dim ipAddress,hostname
ipAddress = "202.172.1.72"

On Error Resume Next
Set objWMIService = GetObject("winmgmts:\\" & ipAddress & "\root\cimv2")
  If Err.Number <> 0 Then
    hostname = "Cannot resolve hostname"
    Err.Clear
  Else
   Set colItems = objWMIService.ExecQuery("Select * FROM Win32_ComputerSystem", "WQL", _
     wbemFlagReturnImmediately + wbemFlagForwardOnly)
   For Each objItem In colItems
     hostname = objItem.Name
   Next
  End If

WScript.Echo "Resolved computer name : '" & hostname & "'"

Get Hostname for set of IP addresses and Export to CSV:

Use the below vbscript code to resolve machine name for multiple IP addresses and export output into csv file. First create the text file IP-Addresses.txt which includes one IP address in each line. You will get the computer name and IP address list in the csv file HostNames.csv.
Dim ipaddressTxtFile,outCSVFile
Dim csvColumns,ipAddress,hostname
Const ForReading = 1

'Create CSV file 
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
outCSVFile ="C:\HostNames.csv"
Set objCSVFile = objFSO.CreateTextFile(outCSVFile, _ 
    ForWriting, True)
'Write comma delimited list of columns in CSV output file.
csvColumns = "IPAddress,HostName"
objCSVFile.Write csvColumns
objCSVFile.Writeline

'Set path of text file which contains set of IP Addresses (one ip address per line).
ipaddressTxtFile = "C:\IP-Addresses.txt"
' Open the file for reading.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(ipaddressTxtFile, ForReading)

' Read the IP addresses from text file and find its computer name.
Do Until objFile.AtEndOfStream
' Read IP address
ipAddress = objFile.ReadLine

On Error Resume Next
Set objWMIService = GetObject("winmgmts:\\" & ipAddress & "\root\cimv2")
  If Err.Number <> 0 Then
    hostname = "Cannot resolve hostname"
    Err.Clear
  Else
   Set colItems = objWMIService.ExecQuery("Select * FROM Win32_ComputerSystem", "WQL", _
     wbemFlagReturnImmediately + wbemFlagForwardOnly)
   For Each objItem In colItems
     hostname = objItem.Name
   Next
  End If

'Write IP address and computer name into CSV file
objCSVFile.Write ipAddress & "," 
objCSVFile.Write hostname & ""
objCSVFile.Writeline

Loop
Note: If you open the csv file using MS Excel, the line should comes in a single cell, to fix this issue, copy the content of the csv file and paste in new text file and save it as new .csv file.

Saturday, 11 July 2015

C# : Get Executing Assembly Folder Path

In C#, we can read directory path of executing assembly file using different methods. In this article, I am going write C# code sample to get executing assembly directory path using Assembly and AppDomain classes.

Get Executing Assembly Folder Path using CodeBase:

public static string GetAssemblyPathByCodeBase()
{
    string codeBase = Assembly.GetExecutingAssembly().CodeBase;
    UriBuilder uri = new UriBuilder(codeBase);
    return Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path));
}

Read Executing Assembly Directory Path using Assembly Location:

public static string GetExecutingDirectoryByAssemblyLocation()
{
    string path= Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    return path;
}

Get Executing Assembly Folder Path using AppDomain:

public static string GetExecutingDirectorybyAppDomain()
{
    string path = AppDomain.CurrentDomain.BaseDirectory;
    return path;
}

Import Bulk AD Users from CSV using C#

In this article. I am going write C# code samples to create bulk AD users from CSV file and create bulk AD users for testing purpose.

Before proceed, consider the CSV file NewUsers.csv which contains set of new Active Directory users to create with the column headers Name, samAccountName and ParentOU.

Create Bulk AD Users from CSV in C#

Note: The value of ParentOU should be enclosed with double quote ("). like "OU=TestOU,DC=TestDomain,DC=Local" since it has the special character comma (,). because in csv file the comma (,) is the key character to split column headers. (Ex file: Download NewUsers.csv)).

We are using the Visual basic class TextFieldParser to read CSV file in C#, to use this class we need to add reference dll Microsoft.VisualBasic.


Create Bulk AD Users from CSV using C#

Create Bulk AD Users from CSV file:

using Microsoft.VisualBasic.FileIO;
using System.DirectoryServices;
// ---------------------------
public static void CreatBulkADUsersFromCSVFile()
{
    string csv_File_Path = @"C:\NewUsers.csv";
    TextFieldParser csvReader = new TextFieldParser(csv_File_Path);
    csvReader.SetDelimiters(new string[] { "," });
    csvReader.HasFieldsEnclosedInQuotes = true;

    // reading column fields 
    string[] colFields = csvReader.ReadFields();
    int index_Name = colFields.ToList().IndexOf("Name");
    int index_samaccountName = colFields.ToList().IndexOf("samAccountName");
    int index_ParentOU = colFields.ToList().IndexOf("ParentOU");
    while (!csvReader.EndOfData)
    {
       // reading user fields 
        string[] csvData = csvReader.ReadFields();
        DirectoryEntry ouEntry = new DirectoryEntry("LDAP://" + csvData[index_ParentOU]);

        try
        {
            DirectoryEntry user = ouEntry.Children.Add("CN="+csvData[index_Name], "user");
            user.Properties["samAccountName"].Value = csvData[index_samaccountName];
            user.CommitChanges();
            ouEntry.CommitChanges();

            int old_UAC = (int)user.Properties["userAccountControl"][0];
            // AD user account disable flag
            int Flag_Acc_Disable = 2;
            // To enable an ad user account, we need to clear the disable bit/flag:
            user.Properties["userAccountControl"][0] = (old_UAC & ~Flag_Acc_Disable);
            user.CommitChanges();

            user.Invoke("SetPassword", new object[] { "MyP@$$w0rd" });
            user.CommitChanges();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    csvReader.Close();
}

Create Bulk AD Users for Testing:

Use the below C# code to create bulk Active Directory users for testing the purpose.
DirectoryEntry ouEntry = new DirectoryEntry("LDAP://OU=TestOU,DC=TestDomain,DC=local");
 
    for (int i = 0; i < 10; i++)
    {
        try
        {
            DirectoryEntry childEntry = ouEntry.Children.Add("CN=TestUser" + i, "user");
            childEntry.CommitChanges();
            ouEntry.CommitChanges();

            int old_UAC = (int)userEntry.Properties["userAccountControl"][0];
            // AD user account disable flag
            int Flag_Acc_Disable = 2;
            // To enable an ad user account, we need to clear the disable bit/flag:
            userEntry.Properties["userAccountControl"][0] = (old_UAC & ~Flag_Acc_Disable);
            userEntry.CommitChanges();

            userEntry.Invoke("SetPassword", new object[] { "MyP@$$w0rd" });
            userEntry.CommitChanges();
        }
        catch (Exception ex)
        {
 
        }
    }

Friday, 10 July 2015

VBScript to Check if Machine is Online or Offline

In this article, I am going write vbscript sample to check if a given computer is online (up) or offline (down) and vbscript to check ping status of set of hostnames (from text file-txt) and export its output to CSV file.

Vbscript to find if a machine is Online or not:

1. Copy the below example vbscript code and paste it in notepad or a vbscript editor.
2. Save the file with a .vbs extension, for example: PingStatus.vbs
3. Change the hostname with your computer name which you want to check ping status.
4. Double-click the vbscript file (or Run this file from command window) to check machine is active or not.
Dim hostname
hostname = "Your-PC"
Set WshShell = WScript.CreateObject("WScript.Shell")
Ping = WshShell.Run("ping -n 1 " & hostname, 0, True)
Select Case Ping
Case 0 
   WScript.Echo "The machine '" & hostname & "' is Online"
Case 1 
   WScript.Echo "The machine '" & hostname & "' is Offline"
End Select

Export Ping status of set of Computers to CSV file:

Use the below vbscript code to check ping status for multiple machines and get output in csv file. First create the text file HostNames.txt which includes one computer name in each line.
Dim hostTxtFile, outCSVFile,csvColumns,hostName
Const ForReading = 1

' Create CSV file 
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
outCSVFile ="C:\HostStatus.csv"
Set objCSVFile = objFSO.CreateTextFile(outCSVFile, _ 
    ForWriting, True)
' Write comma delimited list of columns in CSV output file.
csvColumns = "Hostname,Status"
objCSVFile.Write csvColumns
objCSVFile.Writeline

' Give the path of text file which contains set of hostnames (one hostname per line).
hostTxtFile = "C:\HostNames.txt"
' Open the file for reading.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(hostTxtFile, ForReading)

' Read the computer names from text file and check ping status.
Do Until objFile.AtEndOfStream
' Read computer name
hostName = objFile.ReadLine
Set WshShell = WScript.CreateObject("WScript.Shell")
Ping = WshShell.Run("ping -n 1 " & hostName, 0, True)
Select Case Ping
Case 0 
        objCSVFile.Write hostName & "," 
        objCSVFile.Write "Online" & ""
Case 1 
        objCSVFile.Write hostName & "," 
        objCSVFile.Write "Offline" & ""
End Select
objCSVFile.Writeline

Loop
Note: If you open the csv file using MS Excel, the line should comes in a single cell, to fix this issue, copy the content of the csv file and paste in new text file and save it as new .csv file.

Thursday, 9 July 2015

Network : There are currently no logon servers available to service the logon request

Problem:

You might have received the error "There are currently no logon servers available to service the logon request" in Active Directory domain network environment when you connect your Windows 7/Windows 8 client machine or member server.

DC down : There are currently no logon servers available to service the logon request

Cause:

You will get this message when trying to log in with a domain account but there are no logon servers (domain controllers) available to authenticate your credentials and there is no cached domain password for the domain user account. The following are the possible causes for the error "There are currently no logon servers available to service the logon request":

     - All the logon servers (domain controllers) may be down.
     - Domain controllers may not be reachable through current network connection.
     - If you are trying to login with domain account when computer is not connected with any valid AD Domain.

Wednesday, 8 July 2015

ADUC: How to view child objects of AD User, Computer and Group

By default, we can't view child objects objects of user, computer and group in Active Directory Users and Computers console. If you use any third party software tools to manage Active Directory objects, there may be a possibility to store user's specific information in classStore object under every user accounts. In that case, you need check the options "Users, Contacts, Groups and Computers as containers" and "Advanced Features" to see child objects.

- Open Active Directory Users and Computers console (ADUC).
- Click View > and check the options "Users, Contacts, Groups and Computers as containers" and "Advanced Features".
ADUC: How to view child objects of AD User, Computer and Group

- Now, you can view AD users as like tree node and you can view child objects by expanding tree node.

ADUC: How to view child objects of AD User, Computer and Group

Get hostname from ip address and vice versa in cmd

We can resolve hostname from ip address using ping command in cmd (command prompt) and we can also get ip address of a specified computer using ping command.

Resolve Hostname from IP Address in CMD:

Normally, we use ping command to check whether a machine is online or not. we can get machine name from ip address by giving extra parameter -a with ping command.
ping -a  100.82.151.16
Get hostname from ip address in cmd

Get IP Address from Computer name in CMD:

This may be funny (:: if you already know, we can get ip address from machinename with ping command.
ping hp-PC
Get IP Address from Computername in CMD

C# : Get Special Folder Path (Desktop, StartMenu, Program data)

In C#, we can get the path of a special folder, such as Desktop, Program Files, Programs, Start Menu and Startup using the .net function Environment.GetFolderPath. and we can also get All User's common profile path by using the API ("shell32.dll") function SHGetSpecialFolderPath.

Get System Special Folder Path:

Use the below C# code to retrieve the system special folder path.
string programFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
Console.WriteLine(programFilesPath);

string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
Console.WriteLine(systemPath);

Get Current User Special Folder Path:

string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// Returns current user's desktop profile path like: C:\Users\Morgan\Desktop
Console.WriteLine(desktopPath);
            

string startMenuPath = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
// Ex: C:\Users\Morgan\AppData\Roaming\Microsoft\Windows\Start Menu
Console.WriteLine(startMenuPath);

Get All Users Profile Path (Common Special Folder Path):

You can get common profile path for All Users by using API function SHGetSpecialFolderPath. The below C# method gets common desktop profile path and all users start menu programs folder path.
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x19;
const int CSIDL_COMMON_STARTMENU = 0x16;
public static void GetCommonProfilePath()
{
    StringBuilder allUserProfile = new StringBuilder(260);
    SHGetSpecialFolderPath(IntPtr.Zero, allUserProfile, CSIDL_COMMON_DESKTOPDIRECTORY, false);
    string commonDesktopPath = allUserProfile.ToString();
    //The above API call returns: C:\Users\Public\Desktop 
    Console.WriteLine(commonDesktopPath);


    SHGetSpecialFolderPath(IntPtr.Zero, allUserProfile, CSIDL_COMMON_STARTMENU, false);
    //The above API call returns: C:\ProgramData\Microsoft\Windows\Start Menu
    string startMenuPrograms = Path.Combine(allUserProfile.ToString(), "Programs");
    Console.WriteLine(startMenuPrograms);
}
The API function SHGetSpecialFolderPath also supports to get the path of following special folders:
const int CSIDL_APPDATA = 0x1a;
const int CSIDL_COMMON_APPDATA = 0x23;
const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x19;
const int CSIDL_COMMON_DOCUMENTS = 0x2e;
const int CSIDL_COMMON_MUSIC = 0x35;
const int CSIDL_COMMON_OEM_LINKS = 0x3a;
const int CSIDL_COMMON_PICTURES = 0x36;
const int CSIDL_COMMON_PROGRAMS = 0x17;
const int CSIDL_COMMON_STARTMENU = 0x16;
const int CSIDL_COMMON_STARTUP = 0x18;
const int CSIDL_COMMON_TEMPLATES = 0x2d;
const int CSIDL_COMMON_VIDEO = 0x37;
const int CSIDL_COOKIES = 0x21;
const int CSIDL_DESKTOP = 0;
const int CSIDL_DESKTOPDIRECTORY = 0x10;
const int CSIDL_DRIVES = 0x11;
const int CSIDL_FAVORITES = 6;
const int CSIDL_FLAG_CREATE = 0x8000;
const int CSIDL_FLAG_DONT_VERIFY = 0x4000;
const int CSIDL_FONTS = 20;
const int CSIDL_HISTORY = 0x22;
const int CSIDL_INTERNET_CACHE = 0x20;
const int CSIDL_LOCAL_APPDATA = 0x1c;
const int CSIDL_MYMUSIC = 13;
const int CSIDL_MYPICTURES = 0x27;
const int CSIDL_MYVIDEO = 14;  
const int CSIDL_PERSONAL = 5;
const int CSIDL_PROGRAM_FILES = 0x26;
const int CSIDL_PROGRAM_FILES_COMMON = 0x2b;
const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x2c;
const int CSIDL_PROGRAM_FILESX86 = 0x2a;
const int CSIDL_PROGRAMS = 2;
const int CSIDL_RECENT = 8;
const int CSIDL_SENDTO = 9;
const int CSIDL_STARTMENU = 11;
const int CSIDL_STARTUP = 7;
const int CSIDL_SYSTEM = 0x25;
const int CSIDL_SYSTEMX86 = 0x29;
const int CSIDL_TEMPLATES = 0x15;
const int CSIDL_WINDOWS = 0x24;

How to assign Date variable in Powershell

You can set datetime value to a variable by using Get-Date cmdlet and we can also a convert date string to datetime object using simple DateTime casting.

This assigns the current date time value to the variable $a
$a = Get-Date
Use the below script if you want to get date object from specific date value.
$a = Get-Date "07/06/2015 05:00 AM"
You can also achieve this by using simple DateTime casting
$a = [DateTime] "07/06/2015 05:00 AM"

Tuesday, 7 July 2015

Powershell: Find difference between two Dates

We can easily find difference between two dates with powershell. We can get difference in Days, Hours, Minutes and Seconds.

Total Days between two dates:

The below powershell script show the total number of days between two dates.
$FromDate  =[DateTime] "04/20/2015"
$ToDate      =[DateTime] "07/07/2015"

($ToDate - $FromDate).TotalDays

Total Hours between two dates:

The below powershell script show the total number of hours between two times.
$FromDate =[DateTime] "07/05/2015"
$ToDate     =[DateTime] "07/07/2015"

($ToDate - $FromDate).TotalHours

Total Minutes between two times:

$FromDate = [DateTime] "07/07/2015 1:47:31 PM"
$ToDate     = [DateTime] "07/07/2015 3:47:31 PM"

($ToDate - $FromDate).TotalMinutes

Monday, 6 July 2015

C# - Check current machine is Domain Controller or not

We can determine whether the current machine is domain controller or not by checking Domain Role of the computer in Active Directory environment. We can also ensure if the machine DC or not by checking the Active Directory Domain Services is installed or not in current system.

Check if current machine is DC or not by Domain Role in C#:

The below C# code retrieve the Domain Role information of current machine using the WMI class Win32_ComputerSystem. If the value of Domain Role is greater than 3 then the machine is domain controller or else, it is just a computer or member server.
using System.Management;
//----------------
public static bool IsThisMachineIsDC()
{
    bool is_this_DC = false;
    try
    {
        ManagementScope wmiScope = new ManagementScope(@"\\.\root\cimv2");
        wmiScope.Connect();
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher(wmiScope, new ObjectQuery("SELECT DomainRole FROM Win32_ComputerSystem"));
        foreach (ManagementObject shareData in moSearcher.Get())
        {
            int domainRole = int.Parse(shareData["DomainRole"].ToString());
            if (domainRole >= 4)
            {
                is_this_DC = true;
            }
            break;
        }
    }
    catch (Exception ex)
    {
    }
    return is_this_DC;
}

Check if current computer is DC or not by Active Directory Domain Services:

The below C# code checks if the Active Directory Domain Services is installed or not by using the WMI class Win32_ServerFeature.
using System.Management;
//----------------
public static bool IsThisMachineIsDC()
{
    bool is_this_DC = false;
    try
    {
        uint uID = 110;
        string search = string.Format("SELECT * FROM Win32_ServerFeature WHERE ID = 110", uID);
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher("root\\CIMV2", search);
        foreach (var output in moSearcher.Get())
        {
            if ((uint)(output["ID"]) == uID)
            {
                is_this_DC = true;
                break;
            }
        }
    }
    catch (Exception)
    {
    }

    return is_this_DC;
}