Tuesday, 24 March 2015

Powershell: Set AD User Must Change Password At Next Logon

We can set AD user property values using powershell cmdlet Set-ADUser. The Set-ADUser cmdlet modifies the properties of an Active Directory user. Normally, you can force an AD user to change password at next logon by setting the AD user's pwdLastSet attribute value as 0, but this Set-ADUser cmdlet supports the extended property ChangePasswordAtLogon, you can directly set True or False value in this property and the cmdlet itself internally update the pwdLastSet attribute.

Powershell command to reset user to change password at next logon:

Set-ADUser -Identity <samAccountName> -ChangePasswordAtLogon $true
The Identity parameter specifies the Active Directory user to modify. You can identify a user by its samAccountName, distinguished name (DN), GUID and SID.

Set Users Specific OU:

You can select AD users from specific OU and set user must change password at next logon by using Get-ADUser and Set-ADUser cmdlets. You can set target OU scope by using the parameter SearchBase in Get-ADUser cmdlet. This following command select and set pwdLastSet attribute value as 0 of the Active Directory users the Organization Unit 'TestOU'.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=Local" |
  Set-ADUser -ChangePasswordAtLogon:$True

Update Specific set of AD Users with Filter:

You can filter sepecific set of AD users by using SQL like filter with Get-ADUser, users who are not familiar with LDAP filter can easily use this filter to get only specific set of AD users
Import-Module ActiveDirectory
Get-ADUser -Filter 'department -like "*Admin*"' |
  Set-ADUser -ChangePasswordAtLogon:$True
You can also use LDAP filter with Get-ADUser powershell cmdlet with more flexibility to filter Active Directory users.
Import-Module ActiveDirectory
Get-ADUser -LDAPFilter '(Department=*Admin*)' |
  Set-ADUser -ChangePasswordAtLogon:$True

Modify Bulk AD Users Password Never Expire flag from CSV:

You can read Active Directory from csv file using Powershell cmdlet Import-CSV. Consider the CSV file ADUsers.csv (Ex file: Download ADUsers.csv) which contains set of AD users with the attribute samAccountName.

Set Bulk AD Users to Change Password At Next Logon from CSV
Import-Module ActiveDirectory
Import-Csv "C:\Scripts\ADUsers.csv" | ForEach-Object {
 $samAccountName = $_."samAccountName"
Get-ADUser -Identity $samAccountName | 
 Set-ADUser -ChangePasswordAtLogon:$True
}

Modify specific AD Group Members:

You can set user must change password at next logon for the specific AD group members by getting group members using Get-ADGroupMember cmdlet. The following powershell script select all the members TestGroup group and set the users to change password at next logon.
Import-Module ActiveDirectory
Get-ADGroupMember -Identity "TestGroup" |
  Set-ADUser -ChangePasswordAtLogon:$True
Read More...

Friday, 20 March 2015

Powershell: Set AD Users Password Never Expires flag

We can set Active Directory user property values using Powershell cmdlet Set-ADUser. The Set-ADUser cmdlet modifies the properties of an Active Directory user. Normally, you can configure an AD user as password never expire user by setting the flag DONT_EXPIRE_PASSWORD (65536) in the AD user's userAccountControl attribute, but this Set-ADUser cmdlet supports the extended property PasswordNeverExpires, you can directly set value in this property and the cmdlet itself internally update the userAccountControl flag.

Powershell command to Configure Password Never Expires flag:

Set-ADUser -Identity <samAccountName> -PasswordNeverExpires $true
The Identity parameter specifies the Active Directory user to modify. You can identify a user by its samAccountName, distinguished name (DN), GUID and SID.

Modify AD Users from Specific OU:

You can select AD users from specific OU and set as password never expire users by using Get-ADUser and Set-ADUser cmdlets. You can set target OU scope by using the parameter SearchBase in Get-ADUser cmdlet. This following command select and set as password never expires flag of Active Directory users from the Organization Unit 'TestOU'.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=Local" |
  Set-ADUser -PasswordNeverExpires:$True

Update Specific set of AD Users with Filter:

You can filter sepecific set of AD users by using SQL like filter with Get-ADUser, users who are not familiar with LDAP filter can easily use this filter to get only specific set of AD users
Import-Module ActiveDirectory
Get-ADUser -Filter 'department -like "*Admin*"' |
  Set-ADUser -PasswordNeverExpires:$True
You can also use LDAP filter with Get-ADUser powershell cmdlet with more flexibility to filter Active Directory users.
Import-Module ActiveDirectory
Get-ADUser -LDAPFilter '(Department=*Admin*)' |
  Set-ADUser -PasswordNeverExpires:$True

Modify Bulk AD Users Password Never Expire flag from CSV:

You can read Active Directory from csv file using Powershell cmdlet Import-CSV. Consider the CSV file ADUsers.csv (Ex file: Download ADUsers.csv) which contains set of AD users with the attribute samAccountName.

Modify Bulk AD Users Password Never Expire flag from CSV file
Import-Module ActiveDirectory
Import-Csv "C:\Scripts\ADUsers.csv" | ForEach-Object {
 $samAccountName = $_."samAccountName"
Get-ADUser -Identity $samAccountName | 
 Set-ADUser -PasswordNeverExpires:$True
}

Modify specific AD Group Members:

You can set password never expires flag for only specific Active Directory group members by getting AD group members using Get-ADGroupMember cmdlet. The following powershell script select all the members "TestGroup"  group and set as password never expire users.
Import-Module ActiveDirectory
Get-ADGroupMember -Identity "TestGroup" |
  Set-ADUser -PasswordNeverExpires:$True
Read More...

The type or namespace name 'automation' does not exist in the namespace 'system.management'

I have added the reference Assembly System.Management.Automation in my C# application to run PowerShell scripts from C# project. but I am getting following error during compilation of the code.
Error 30 The type or namespace name 'Automation' does not exist in the namespace 'System.Management' (are you missing an assembly reference?)
This is my C# code:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
//-----------------------------------
static void Main(string[] args)
{
    Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript("Get-Date");
    Collection<PSObject> results = pipeline.Invoke();
    runspace.Close();
    StringBuilder stringBuilder = new StringBuilder();
    foreach (PSObject obj in results)
    {
        Console.WriteLine(obj.ToString());
    }
}

Fix/Solution:

The issue was fixed after I have changed the reference of System.Management.Automation to c:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll.

I have added the reference Assembly System.Management.Automation from the location "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0" and my C# projects targets .NET Framework 3.5. Initially I didn't find the the reference System.Management.Automation.dll when I search the Assemblies in Add Reference window, so that I have added the reference by manual browse option from the location "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0".

Finally I found that the assembly file System.Management.Automation.dll (under the folder PowerShell 3.0) is supported only .NET Framework 4.0, so that have changed the reference Assembly to c:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll to fix this issue.
Read More...

Wednesday, 18 March 2015

Change the location of Windows Search Index

If you enabled the Windows Search and Index service in your windows system, the file named "Windows.edb" will be placed under the location "C:\ProgramData\Microsoft\Search\Data\Applications\Windows" and its size will be growing day by day. You have to change the location of the file if you are facing disk storage size overflow problem due to this file.

Change location of Windows Search Index

By default, Search Index file(Windows.edb) stored at C:\ProgramData\Microsoft\Search\Data folder, which is a hidden system folder. You can change the location of the Search Index under Indexing Options in the Control Panel. Follow the steps to change the location of Windows Search Index.

1.  Open Control Panel in its ‘Large Icons view’, and click on Indexing Options.

Change the location of Windows Search Index

2.  In new Window, click on Advanced button.

Change the location of Windows Search Index

3.  Under the Index location section, click Select new button.

Change the location of Windows Search Index

4.  Select the folder where you want to store the new search index file and click on OK.

Change the location of Windows Search Index

Note:This process will restart Windows Search Service and Indexing and save the Search Index file at new location.
Read More...

Tuesday, 17 March 2015

TF400324: Team Foundation services are not available from server...

Problem:

We faced the TFS connection failure problem while connecting TFS source project from Visual Studio 2013. We got the error message "TF400324: Team Foundation services are not available from server - The underlying connection was closed: An unexpected error occurred on a receive".

Complete error message:

TF400324: Team Foundation services are not available from server TFS-Server.
Technical information (for administrator):
 The underlying connection was closed: An unexpected error occurred on a receive.

Solution:

After I have analysed some time, found the following quick fix to resolve this error.
  1. Close Visual Studio Solution and related applications.
  2. Browse the TFS AppData Cache folder path: %LocalAppData%\Microsoft\Team Foundation\5.0\Cache
  3. Delete all the contents under the folder Cache (don't worry it will be automatically re-created when you open Visual Studio and connect TFS again),
For better fix, you can refer this solution: http://www.codeproject.com/Articles/613214/TF-Team-Foundation-services-are-not-availabl
Read More...

C# - Set Full Control Permission to a Directory

In C#, we can easily add full access control permission on a file or folder for an user account or everyone (Everybody) account using .NET classes Directory and DirectorySecurity.

The below C# code set the full control permission on the given directory for the given user account. It also applies the full control permissions to folder, subfolders and files.
public static void SetFullAccessPermission(string directoryPath,string username)
{
    DirectorySecurity dir_security = Directory.GetAccessControl(directoryPath);
            
    FileSystemAccessRule full_access_rule = new FileSystemAccessRule(username,
                     FileSystemRights.FullControl, InheritanceFlags.ContainerInherit |   
                     InheritanceFlags.ObjectInherit,PropagationFlags.None,
                     AccessControlType.Allow);

    dir_security.AddAccessRule(full_access_rule);

    Directory.SetAccessControl(directoryPath, dir_security);
}
In some cases, situation may require us to configure full control permission to every users (Everyone/Everybody account). In that case, get the everyone identity from the enum WellKnownSidType.WorldSid instead of giving the string "Everyone" because the string value "Everyone" differs other languages. The below C# code set full access control permission on the given directory for everyone account.
public static void SetFullAccessPermissionsForEveryone(string directoryPath)
{
    //Everyone Identity
    IdentityReference everyoneIdentity = new SecurityIdentifier(WellKnownSidType.WorldSid,
                                               null);

    DirectorySecurity dir_security = Directory.GetAccessControl(directoryPath);

    FileSystemAccessRule full_access_rule = new FileSystemAccessRule(everyoneIdentity,
                    FileSystemRights.FullControl, InheritanceFlags.ContainerInherit |   
                     InheritanceFlags.ObjectInherit,PropagationFlags.None,
                     AccessControlType.Allow);
    dir_security.AddAccessRule(full_access_rule);

    Directory.SetAccessControl(directoryPath, dir_security);
}
Read More...

Monday, 16 March 2015

Powershell - Export AD Users Report to CSV File

We can generate and export Active Directory users report to CSV file using Powershell cmdlets Get-ADUser and Export-CSV. Get-ADUser cmdlet supports SQL like filter and LDAP filter to filter AD Users. By using these filter we can generate any kind of Active Directory Reports. You can select any user attribute that supported in Active Directory using Get-ADUser cmdlet and it also supports Extended Properties like AccountLockoutTime, Enabled,LockedOut (refer this article:Get-ADUser Default and Extended Properties to know more supported AD attributes).

Export AD Users to CSV using Powershell

The following powershell script exports the selected properties of all Active Directory users to CSV file.
Import-Module ActiveDirectory
Get-ADUser -Filter * -Properties * |
 Select -Property SamAccountName,Mail,Department | 
 Export-CSV "C:\\AllADUsers.csv" -NoTypeInformation -Encoding UTF8

Select Users from specific OU:

We can set target OU scope by using the parameter SearchBase. The following powershell script select all the AD users from the Organization Unit 'TestOU' and export it to CSV file.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=Local" -Properties * |
 Select -Property SamAccountName,Mail,Department | 
 Export-CSV "C:\\TestOUUsers.csv" -NoTypeInformation -Encoding UTF8

Add more Properties in export report:

You can add any extra attribute that supported in Active Directory in property list. If you want to add the attributes displayName and mobile with this script, you can simply add these attributes as comma separated values.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=Local" -Properties * |
 Select -Property SamAccountName,Mail,Department,displayName,mobile | 
 Export-CSV "C:\\ADUsers.csv" -NoTypeInformation -Encoding UTF8
Along with normal attributes, you can also add the Extended Properties like AccountLockoutTime, Enabled, LockedOut  (refer this article:Get-ADUser Default and Extended Properties to know more supported extended AD attributes).
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=Local" -Properties * |
 Select -Property SamAccountName,AccountLockoutTime,Enabled,LockedOut | 
 Export-CSV "C:\\ADUsers.csv" -NoTypeInformation -Encoding UTF8

Apply SQL Like filter to get specific users:

Get-ADUser cmdlet supports SQL like filter, users who are not familiar with LDAP filter can easily use this filter to get only specific set of AD users. This following powershell script export the selected properties to CSV file of AD users whose City contains the text 'Austin'.
Import-Module ActiveDirectory
Get-ADUser -Filter 'City -like "*Austin*"' |
  Select -Property Name,City,Mail,Department,DistinguishedName | 
  Export-CSV "C:\\ADUsers.csv" -NoTypeInformation -Encoding UTF8
You can use both normal AD attribute and Extended Properties in this filter. The following powershell script export all the enabled Active Directory users whose PasswordNeverExpires flag value is equal to False by filtering with Extended Properties Enabled and PasswordNeverExpires.
Import-Module ActiveDirectory
Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} |
  Select -Property Name,Mail,Department,DistinguishedName | 
  Export-CSV "C:\\ADUsers.csv" -NoTypeInformation -Encoding UTF8

Apply LDAP Filter to get specific set of AD users:

If your are familiar with LDAP filter, instead of normal filter, you can also use LDAP filter with Get-ADUser powershell cmdlet with more flexibility to filter Active Directory users. The below script exports all the users who are belongs to Admin department.
Import-Module ActiveDirectory
Get-ADUser -LDAPFilter '(Department=*Admin*)' -Properties * |
  Select -Property Name,Mail,Department,DistinguishedName | 
  Export-CSV "C:\\AdminUsers.csv" -NoTypeInformation -Encoding UTF8
The below powershell script exports only enabled AD users with LDAP filter. Refer this article (AD LDAP Filter Examples) to get more LDAP filter examples.
Get-ADUser -LDAPFilter '(!userAccountControl:1.2.840.113556.1.4.803:=2)' -Properties * |
  Select -Property Name,Mail,Department,DistinguishedName | 
  Export-CSV "C:\\EnabledUsers.csv" -NoTypeInformation -Encoding UTF8

Powershell - Export AD Users CSV output:

Powershell - Export AD Users Report to CSV File
Read More...

C# - Change Service Account Username and Password

In C#, We modify Windows service account username and password using the WMI class Win32_Service and we can also update service account information using the Win32 API function ChangeServiceConfig. In this article, I am going to write C# examples to change service account name and password in local machine and remote machine.

Summary:

Change Service Account Information using Win32 API

Use the below C# sample code to update service account username and password. It uses the Win32 API function ChangeServiceConfig. The ChangeServiceConfig function changes the configuration information for the specified service in the service control manager database.
private const int SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const uint SERVICE_NO_CHANGE = 0xffffffff; //this value is found in winsvc.h
private const uint SERVICE_QUERY_CONFIG = 0x00000001;
private const uint SERVICE_CHANGE_CONFIG = 0x00000002;

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean ChangeServiceConfig(IntPtr hService, UInt32 nServiceType, 
    UInt32 nStartType,UInt32 nErrorControl,String lpBinaryPathName,String lpLoadOrderGroup,
    IntPtr lpdwTagId, [In] char[] lpDependencies, String lpServiceStartName, 
    String lpPassword, String lpDisplayName);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, 
     uint dwDesiredAccess);

[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, 
    CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr OpenSCManager(string machineName, string databaseName, 
     uint dwAccess);

public static bool ChangeServiceAccountInfo(string serviceName, string username,
       string password)
{
    try
    {
        IntPtr scm_Handle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
        if (scm_Handle == IntPtr.Zero)
          throw new System.Runtime.InteropServices.ExternalException(
                      "Open Service Manager Error");

        IntPtr service_Handle = OpenService(scm_Handle, serviceName,
                                        SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
        if (service_Handle == IntPtr.Zero)
          throw new System.Runtime.InteropServices.ExternalException("Open Service Error");
        //Changing the user account and password for the service.
        if (!ChangeServiceConfig(service_Handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, 
             SERVICE_NO_CHANGE, null, null,IntPtr.Zero, null, username, password, null))
        {
            int nError = Marshal.GetLastWin32Error();
            Win32Exception win32Exception = new Win32Exception(nError);
            throw new System.Runtime.InteropServices.ExternalException("Could not change 
          user account and password : " + win32Exception.Message);
        }
        Console.WriteLine("Service account information changed successfully");
        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return false;
    }
}

Change Service Login Username and Password using WMI in C#

The below C# code sample uses the WMI class Win32_Service to update windows service user name and password. To use WMI service, we need to add the reference System.Management;
using System.Management;
//--------------------------
public static void ChangeServiceAccountInfobyWMI(string serviceName, string username,
          string password)
{
    string mgmntPath = string.Format("Win32_Service.Name='{0}'", serviceName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(mgmntPath)))
    {
        object[] accountParams = new object[11];
        accountParams[6] = username;
        accountParams[7] = password;
        object outParams = service.InvokeMethod("Change", accountParams);
        if((uint)outParams ==0)
        {
            Console.WriteLine("Service account information changed successfully");
        }
        else
        {
            Console.WriteLine("Failed to change Service account information");
        }
    }
}

Update Service Account Username and Password in Remote Server

Use the below C# code sample to update windows service user name and password in remote machine using the WMI class Win32_Service. To use WMI service, we need to add the reference System.Management and use admin credentials if required to update service information in remote computer.
using System.Management;
//--------------------------
static void ChangeRemoteServiceAccountInfo(string remoteComputer, string serviceName, 
            string username, string password)
{
    try
    {
        ConnectionOptions connectionOptions = new ConnectionOptions();
        // Use credentials if needed
        //connectionOptions.Username = "Administrator";
        //connectionOptions.Password = "AdminPassword";
        //connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
        ManagementScope scope = new ManagementScope("\\\\" + remoteComputer + 
                                             "\\root\\CIMV2", connectionOptions);
        scope.Connect();
        string mgmntPath = string.Format("Win32_Service.Name='{0}'", serviceName);
        using (ManagementObject service = new ManagementObject(scope,
                                 new ManagementPath(mgmntPath),new ObjectGetOptions()))
        {
            object[] accountParams = new object[11];
            accountParams[6] = username;
            accountParams[7] = password;
            object outParams = service.InvokeMethod("Change", accountParams);
            if ((uint)outParams == 0)
            {
                Console.WriteLine("Service account information changed successfully");
            }
            else
            {
                Console.WriteLine("Failed to change Service account information");
            }
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}
Read More...

Friday, 13 March 2015

Powershell - Get AD Users Password Expiry Date

We can find and list the password expiry date of AD user accounts from Active Directory using the computed schema attribute msDS-UserPasswordExpiryTimeComputed. In PowerShell, we get a list AD Users properties by using the cmdlet Get-ADUser. We can use SQL like filter and LDAP filter with Get-ADUser cmdlet to get only particular set of users.

Summary:

Get Password Expiry Date of all Enabled AD Users

The following powershell script find all the enabled Active Directory users whose PasswordNeverExpires flag value is equal to False and list the attribute value samAccountName and Password Expire Date. The Active Directory computed attribute msDS-UserPasswordExpiryTimeComputed is timeStamp attribute and its value will be stored as integer, so we are using expression to convert timestamp value into normal date time.
Import-Module ActiveDirectory
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
 –Properties "SamAccountName","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName", @{Name="Password Expiry Date"; `
Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | FT
You can add any extra attribute that supported in Active Directory in property list. If you want to add the attributes mail and pwdLastset with this script, you can simply add these attributes as comma separated values.
Import-Module ActiveDirectory
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
–Properties "SamAccountName","mail","pwdLastSet","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName","mail",@{Name="Password Last Set";`
Expression={[datetime]::FromFileTime($_."pwdLastSet")}}, @{Name="Password Expiry Date";`
Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | FT
Instead of normal filter, you can also use LDAP filter with Get-ADUser powershell cmdlet to filter Active Directory users.
Import-Module ActiveDirectory
Get-ADUser -LDAPFilter '(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(!userAccountControl:1.2.840.113556.1.4.803:=65536))'`
–Properties "SamAccountName","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName", @{Name="Password Expiry Date";`
Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | FT
Here, the userAccountControl flag value 2 indicates disabled account status and the flag 65536 indicates PasswordNeverExpires.

Powershell - Get AD Users Password Expiry Date

Get AD Users Password Expiration Report from Specific OU

We can set target OU scope by using the parameter SearchBase in powershell's Get-ADUser cmdlet. This following command select and list all the enabled AD users password expiration report from the Organization Unit 'TestOU'.
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=TestOU,DC=TestDomain,DC=Local"`
 -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
–Properties "SamAccountName","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName", @{Name="Password Expiry Date";`
Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | FT

Export AD Users Password Expiration Report to CSV with Powershell

We can export powershell output into CSV file using Export-CSV cmdlet. The following powershell command export selected properties and password expiry date of all the enabled Active Directory users to CSV file.
Import-Module ActiveDirectory
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
–Properties "SamAccountName","mail","pwdLastSet","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName","mail",@{Name="Password Last Set";`
Expression={[datetime]::FromFileTime($_."pwdLastSet")}}, @{Name="Password Expiry Date";`
Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | 
 Export-CSV "C:\\PasswordExpirationReport.csv" -NoTypeInformation -Encoding UTF8

CSV Output of AD Users Password Expiration Date Report:

Export AD Users Password Expiration Report to CSV with Powershell
Read More...

Kill a process that won't die when you use End Task in Task Manager

Problem:

Unfortunately, today I have executed a time consuming powershell script through Windows Powershell Command utility. I have waited so much of time to get result but there was no luck, So have decided to terminate the program (kill a process) but it ignores any attempt by Task Manager to kill the process.

Solution: Kill or Terminate a not responding process

After I have analyzed some time found the below solutions for this issue.

Solution 1:

- In Task Manager, go to under the tab Applications and right-click on the program that you want to kill and click Go To Process.
Kill a process that won't die when you use End Task in Task Manager
- Then right-click on the highlighted process and click on End Process. You can also try with End Process Tree.

Solution 2:

- You can also use the utility program "Process Explorer" written by Mark Russinowich of Sysinternals...it is available at the Microsoft website....Download the utility from this link: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
- Run the Process Explorer utility, locate and kill the corresponding prcoess.

Kill a process that won't die when you use End Task in Task Manager
Read More...

Thursday, 12 March 2015

Powershell – Check If File Exists or Not

We can check and test if a file or folder exist or not by using the PowerShell cmdlet Test-Path.

The below powershell script will check whether the file test.txt is already exists or not under the path C:\Share\.
$FileName = "C:\Share\test.txt"
if (Test-Path $FileName) 
{
  Write-Host "File Exists"
}
else
{
  Write-Host "File Not Exists"
}
Read More...

Powershell – Delete File If Exists

We can test and check if a file exist or not by using the PowerShell cmdlet Test-Path and we can remove/delete a file by using the cmdlet Remove-Item.

The below powershell script delete the file test.txt if it already exists under the path C:\Share\.
$FileName = "C:\Share\test.txt"
if (Test-Path $FileName) 
{
  Remove-Item $FileName
}
Read More...

GPO Update Failed - User and Computer policy could not be updated successfully

Problem:

I am using Windows Server 2008 R2 , today, I have modified some settings in one of Group Policy and as usual I have tried the command gpupdate / force to update gpo settings. After some time, I have receive the error "User policy could not be updated successfully" and "Computer policy could not be updated successfully".

User policy could not be updated successfully. The following errors were encountered:

The processing of Group Policy failed. Windows attempted to read the file \\TestDomain.local\sysvol\TestDomain.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\gpt.ini from a domain controller and was not successful. Group Policy settings may not be applied until this event is resolved. This issue may be transient and could be caused by one or more of the following:
a) Name Resolution/Network Connectivity to the current domain controller.
b) File Replication Service Latency (a file created on another domain controller has not replicated to the current domain controller).
c) The Distributed File System (DFS) client has been disabled.

Computer policy could not be updated successfully. The following errors were encountered:

Fix/Solution: 

Browse the Sysvol directory (\\domainname\Sysvol\) from Start\Run. then you will get below error message. .
Network Error-Windows cannot access \\domainname\sysvol\

Check the spelling of the name. Otherwise, there might be a problem with your network. To try to identify and resolve network problems, Error code: 0x800704cf - The network location cannot be reached. For information about network troubleshooting, see Windows Help.
If you got this error message, you are facing the same problem that I faced. Then try to browse the Sysvol directory by Domain Controller name or FQDN (\\DC1\Sysvol\) instead of domain name from Start\Run. now you can access the sysvol without any problem, so the ultimate cause for this issue is Name Resolution/Network Connectivity problem. The root cause of the Name Resolution will differs for every environment.

In my environment, I have fixed the Name Resolution issue by following below steps:

- Checked Name Resolution by Ping command (Ping YourDomain.local)
- Ping result shows, it is trying to connect wrong IP address instead of IP of current DC, and ensured the wrong IP address is nothing but the IP of my another DC which is not active.

Finally, I have confirmed this is the root cause for my problem, the IP address of inactive DC is cached in DNS entries for the domain name, Now, I started that DC and confirmed everything is working fine now.

Note: Name Resolution/Network Connectivity problem is generic DNS problem, so please try to resolve DNS cache issue as per your own need.

Other Useful References:

- http://support.microsoft.com/kb/934907
- https://social.technet.microsoft.com/Forums/windowsserver/en-US/2a1dae75-90bb-43c3-963e-b5a668f4fd33/gpupdate-returns-event-id-1058-error-code-53
- https://social.technet.microsoft.com/Forums/en-US/d8f2b1a0-17a3-4756-b2de-7ffbd9bf1d92/user-policy-could-not-be-updated-successfully-the-following-errors-were-encountered-please-help-me?forum=winserverGP
Read More...

Wednesday, 11 March 2015

Get NTFS File Permissions with PowerShell script

We can read the owner and permissions of a file, folders and registry keys with Powershell’s Get-Acl cmdlet. In this article, I am going to write poweshell script samples to read file permissions, folder level permissions and export folder level permissions to csv file.

Summary:

The below command read and list the permissions of the folder.
Get-Acl -path "C:\Windows"
The above command displays Access Control List as combined text. So the output may not give clear idea about who has what permissions. We can get clear ACL information by expanding the individual ACEs (access control entries) using the parameter expand
Get-Acl -path "C:\Windows" | Select -expand Access 
When you read permissions by using Get-Acl cmdlet, you can notice some of the entries display the number 268435456 as FileSystemRights. This number is nothing but the Full Controll permission. (Powershell can't resolve following special permissions: Modify, Delete, FullControl -> -1610612736, –536805376, and 268435456).

Read NTFS File Permissions with filter in PowerShell:

You can filter files in the provider's format or language. The value of this parameter qualifies the Path parameter. The syntax of the filter, including the use of wildcards, depends on the provider. The following script get permissions of all the files under the directory C:\Windows.
Get-Acl C:\Windows\*.* | FL
The following script read permissions of all the log files under the directory C:\Windows.
Get-Acl C:\Windows\*.log | FT
The following script read permissions of all the files from the directory C:\Share and its sub-directory by recursively. The where filter $_.PsIsContainer -eq $false excludes the folders and list only files.
Get-ChildItem "C:\Share" -recurse |  where {$_.PsIsContainer -eq $false} | Get-Acl | FT

Read NTFS Folder Level Permissions in PowerShell:

The following PowerShell command read all the sub folders from C:\Share by recursively and list the permissions of the sub folders. The where filter $_.PsIsContainer -eq $true excludes the files and list only folders.
Get-ChildItem "C:\Share" -recurse | where {$_.PsIsContainer -eq $true} | Get-Acl | FT

Export Folder Permissions to CSV with PowerShell:

The following PowerShell script will export all NTFS Folder permissions to a CSV file. Change the $RootPath variable to your own root folder path that you want to export permissions . You can also change the name and location of the CSV file by modifying the $CSV_File_Path variable.
$CSV_File_Path = "C:\Permissions.csv"
$Header = "Folder Path,Identity Name,Access,IsInherited,InheritanceFlags,PropagationFlags"

If (Test-Path $CSV_File_Path){
 Remove-Item $CSV_File_Path
}

Add-Content -Value $Header -Path $CSV_File_Path 

$RootPath = "C:\Share"

$Folders = Dir $RootPath -recurse | where {$_.PsIsContainer -eq $true}

foreach ($Folder in $Folders){
 $ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access  }
 foreach ($ACL in $ACLs){
 $permission = $Folder.Fullname + "," + $ACL.IdentityReference  + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
 Add-Content -Value $permission -Path $CSV_File_Path
 }}
Read More...

Concatinate string and Int in SQL server

In this article, I am going to write t-sql query to concatinate two strings and concatinate string and Int in SQL server.
You can concatinate or combine two or more string values using + operator in SQL Server. The + operator returns a string that is the result of concatenating two or more string values.
Declare @str1 varchar(50) ='hello'
Declare @str2 varchar(50) ='world'
SELECT (@str1+' '+@str2) as Result
You can also concatinate two different data type values using + operator. But you need to convert the all ther values into single data type before concatinate the values.

Concatinate string and Int as string value in SQL server

Declare @str1 varchar(50) ='hello'
Declare @int1 int =10
SELECT (@str1+' '+cast(@int1 as varchar(50))) as Result

Concatinate string and Int as integer value in SQL server

Declare @str1 varchar(50) ='100'
Declare @int1 int =10
SELECT (cast(@str1 as int)+@int1) as Result

Note:

If you are using SQL Server 2012 and later versions, you can concatinate or combine two or more string values using CONCAT function. The CONCAT function returns a string that is the result of concatenating two or more string values.
SELECT CONCAT ( 'Happy ', 'Birthday ', 11, '/', '25' ) AS Result;
You will get below error, if your run this query in older version of SQL Server like SQL Server 2008 r2.
Msg 195, Level 15, State 10, Line 1
'CONCAT' is not a recognized built-in function name.
Read More...