Posts

Showing posts from 2016

Powershell Custom Object Formatting

Image
Today I would like to share some guidelines on how to apply formatting to custom powershell objects. There are many times when writing advanced functions, cmdlets and modules where a custom object is very useful, so let's start by creating an object type for our custom objects. Creating a type is very simple, you just define the type as you would in C# and then add it: add-type @' namespace TestModule.CustomObject { public class ExchangeServerMaintenanceMode { public string Name; public bool Enabled; public int ID; } } '@ I should also add here that Powershell 5 makes it even easier by allowing us to create classes directly! Now that we have added the type of our custom object, lets create some objects! $myuser = New-Object TestModule.CustomObject $myuser .Id = "1" $myuser .Name = "User1" $myuser .Enabled = $false Here, we have created a new object of type TestModule.CustomObject and we

Exchange Shell Colors

Image
You may have noticed that the output of the Write-Verbose - and possibly the color of other "Write-" commands - may change when using standard powershell, exchange shell or other flavors of powershell compared to the Powershell ISE. I'm a very big fan of ISE so I wanted to change the colors in order to match the ones in ISE. You can see the colors that are configured on your powershell window using the command ( Get-Host ).PrivateData You'll get something like this Now that we have a way to see the colors that are configured, what about a way to change them? First, we'll save the output of the above command to a variable: $colors = ( Get-Host ).PrivateData We are now able to update the color we want by just setting the proper property of the variable: $colors .VerboseForegroundColor = "Cyan" Put that in your $profile file and you won't have to worry about colors again!

Exchange Server Relay Receive Connector

Microsoft Exchange servers do not allow SMTP relay by default so you have to configure it yourself. But, before you allow relaying, make sure this is want you need. Let's go over a simple design for relaying. First of all, you have to create new receive connectors with the appropriate permissions. Make sure the "Anonymous" access is enabled and that the servers that need to relay are configured on the Remote IP Ranges. This way, only these servers will be able to relay. I also create A records in the DNS servers that point to the servers with the connectors and set the record's name as the HELO/EHLO response of the connectors. The following commands will extend the receive connectors in order to accept messages for any sender and accept any sender: Get-ReceiveConnector "Relay Exchange 1" |     Add-ADPermission -User 'NT AUTHORITY\Anonymous Logon' -ExtendedRights MS-Exch-SMTP-Accept-Any-Recipient Get-ReceiveConnector "Relay Ex

Exchange Server Recipient Type Values for MSExchRecipientTypeDetails Active Directory Attribute

There are many times where I need to get the type of an exchange recipient but all I have is Active Directory access and not Exchange. A typical scenario is during a migration where you may only have AD access for MIM to sync the directories. How are we going to get the exchange recipient with only AD access? Using the MSExchRecipientTypeDetails Active Directory attribute. Below is the table with the possible values for that attribute. Object Type RecipientTypeDetails Value Name User Mailbox 1 UserMailbox Linked Mailbox 2 LinkedMailbox Shared Mailbox 4 SharedMailbox Legacy Mailbox 8 LegacyMailbox Room Mailbox 16 RoomMailbox Equipment Mailbox 32 EquipmentMailbox Mail Contact 64 MailContact Mail User 128 MailUser Mail-Enabled Universal Distribution Group 256 MailUniversalDistributionGroup Mail-Enabled Non-Universal Distribution Group 512 MailNonUniversalGroup Mail-Enabled Universal Security Group 1024 MailUniversalSecurityGroup Dynamic

Verbose Parameter Passing to cmdlet inside Function

Well, almost all powershell cmdlets, functions and workflows have a Verbose parameter that displays more information about what the command is doing during it's execution. But how are we going to take advantage of this parameter when building our own functions and scripts? First of all, we have to include the "cmdletBinding()] statement. This will add the -Verbose switch to the function/script and when we call the function with that script the output from the command "Write-Verbose" will be displayed. Take the following function for example: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Function Test { [ cmdletBinding ()] Param ( ) Write-Verbose "Started" Start-Sleep -Seconds 5 Write-Verbose "Completed." } All it does is sleep for five seconds. If we call it without the -Verbose switch it will display nothing. With the -Verbose switch it will display the "Started" message before sleeping a

How To Write to the Event Log in C#

I've been doing a lot of C# developing for Microsoft Exchange lately and I would like to share with you a few lines of C# that I've found to be very useful in event handling. I prefer using the windows event logs and not text files for logging since they will not grow out of control and are very easy to search and handle. The function below will create an event in the specified log, under the specified source with the provided information: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private static void WriteEvent (String LogName, String EventSource, String EventBody, int EventId, EventLogEntryType EventType) { try { using (EventLog eventLog = new EventLog(LogName)) { if (!EventLog.SourceExists(EventSource)) EventLog.CreateEventSource(EventSource, LogName); eventLog.Source = EventSource; eventLog.W

Powershell: How to pass a parameter to a scriptblock

Scriptblock. Very common in the powershell world and used by many cmdlets and functions like Invoke-Command. But how can we pass a parameter to the scriptblock? Lets say that we are developing a function that will execute a command on remote computers. As a real world example, I want to check the status of a service on remote computers. I need however my function to be agile and accept the name of the service to check. Since I am going to be using the Invoke-Command cmdlet, I need to pass the name of the service to the scriptblock parameter. Fortunatelly, this is fairly easy and cam be accomplished using the param statement in the scriptblock just like: Invoke-Command -ComputerName $Computer ` -ScriptBlock { param ( $ServiceName ) Get-Service -Name $ServiceName } ` -ArgumentList $ServiceName Of course, the Get-Service has a ComputerName parameter for this purpose but this is just an example.

Getting Exchange Server Recipients from Active Directory

I run into a strange issue today where I had to get a list of all the users that had a mailbox without having access to any Exchange servers. It was crucial that the list did not contain any MailUsers or MailContacts since those objects are managed using Microsoft Identity Manager (MIM). Since I could not access any Exchange servers, the use of the Get-Mailbox cmdlet was out of the question. I had to go to the source, the Active Directory. Exchange depends heavily on Active Directory and that was the place I would find the information I needed. So, I fired up Powershell ISE and loaded the activedirectory module. In order to filter the objects, we are going to use the msExchRecipientTypeDetails attribute. The values of this attribute represent the different Exchange Recipient Types. You can find more details about the values here: https://blogs.technet.microsoft.com/dkegg/2014/05/09/msexchrecipienttypedetails/ Since I only want the users with a mailbox, I am going to use the Get-A

Windows Server 2012 R2 Core Setup Part 3

This is the third and final article of the series, following the  Windows Server 2012 R2 Core Setup Part 2,  where we will update the server with the latest updates. In many Windows Server Core installations, I've seen people use Corefig, a very easy and handy utility to configure many things on a core server. I'm not going to demonstrate that though because this is a Powershell only guide! Instead we are going to use a Powershell module for Windows Update named PSWindowsUpdate. After you download the file, unblock it using: UnBlock -File -Path .\PSWindowsUpdate.zip and extract the contents. When the extraction is finished, import the module using: Import-Module .\PSWindowsUpdate Use the path to the module's top level directory, that is the directory that contains all the files in order to import it. Now that we have the PSWindowsUpdate module installed, we will focus on two of the commands, Get-WUList and Get-WUInstall The first one wil

Windows Server 2012 R2 Core Setup Part 2

Let's continue the Windows Server Core setup from where we left it in the previous article of the series! We will start by enabling the Remote Desktop firewall rules so you can connect to the server remotely: Enable-NetFirewallRule -DisplayGroup "Remote Desktop" Next, it's time to allow access to administrative file shares like c$ using: Enable-NetFirewallRule -DisplayGroup "File and Printer Sharing" Some monitoring systems use ping to test if a system is up, in that case we have to allow it through the firewall: Get-NetFirewallRule -Name FPS-ICMP4-* | Enable-NetFirewallRule Those rules are part of the File and Printer Sharing group and will be enabled if you enable the group. Now that we have allowed the Remote Desktop connections through the firewall, it's time to check if Remote Desktop is enabled and if not, enable it. First, we will use the following command to check if Remote Desktop is enabled: ( Get-ItemPro

Windows Server 2012 R2 Core Setup

In this article I will show you the commands I usually use in order to configure a newly set up Windows Server 2012 R2 system. I know there are may other ways to do this like sconfig or corefig but I prefer native Powershell command. Let's start by renaming the computer with the command below: Rename-Computer -NewName Server1 A small note here, the name of the computer will not change until you reboot. If you want to reboot right after the cmdlet above completes just add the -Restart parameter. Next, I'm going to set the product key: slmgr -ipk productkeystring After the step above I like to configure the network settings. Let's start with renaming the network adapters. That way it is easier to tell which adapter is connected to which network: Rename-NetAdapter -NewName LAB_Data After renaming the adapters, it's time to assign some IP addresses! New-NetIPAddress -IPAddress 10.0.0.12 ` -InterfaceAlias LAB_Data ` -DefaultGateway 10.0.0.1 `

Active Directory Certificate Services Installation Error

Image
I got a call today from a friend that had a strange issue when opening the Certification Authority mmc snap-in. When tried to open the certification authority he got the following message: Although this seems very serious, it is nothing other that expected. As it turns out, he was setting up a lab and part of the lab was testing the certificate services. After adding the role and features though, you have to finish the configuration. Right click on the yellow triangle on the top right of the Server Manager to get the respective prompt. After the configuration is complete, the MMC snap-in is working as expected.

IPFire Network Interface Not Found

Today I'd like to talk about IPFire and a problem I had recently with the network cards. IPFire is my favourite lightweight firewall distribution. It's easy to setup and configure which, in my opinion, makes it perfect for labs and POCs. I have a lab environment set up on my Windows 10 computer with multiple virtual networks and virtual machines. I have setup a virtual network with Active Directory domain controllers acting as DCHP and DNS servers, several test servers and workstations. I have even joined an Ubuntu Server to this Active Directory Domain. All these in a private virtual network... So I had to make internet connection available to those machines. I created a new virtual machine and installed IPFire. I added three virtual network adapters to the virtual machine - one connected to my LAN and the other two connected to two private virtual networks. After a little bit of configuration, my virtual machines could access the internet through the IPFire virtual m

Microsoft Exchange Distribution Group Permission Error

Image
So, you're an Exchange administrator and you have been assigned the task to add multiple recipients to distribution lists. You fire up Powershell, load the Exchange snap-ins and after you have your recipients ready you start adding them to the groups. If a group has managers configured and you're not a manager of the group, the Add-DistributionGroupMember  or  Remove-DistributionGroupMember cmdlets will fail with an OperationRequiresGroupManager exception just like this one: The solution to this is very simple, you have to add the -BypassSecurityGroupManagerCheck  switch to your command. When adding or removing many members I always use this switch cause I do not want to get an error and end up with users being added to some groups just for this reason. Never the less, you can always use Try-Catch to handle the exception or check if the group has managers if you do not want to bypass this check for all groups. You may find more information regarding this exceptio

Kali Linux Screen Resolution

Kali Linux is an operating system that is - without any doubt - a very useful tool for everyone that is in the IT business. It contains tools to not only check the security of systems but also help examine  and troubleshooting network issues, application issues etc. I've always used Microsoft Windows as my primary operating system and since Hyper-V is available out of the box the last few years, all my virtual machines are running on Hyper-V. Installing Kali Linux 2 on a virtual machine is pretty straight forward, assign the .iso file to the virtual machine's drive, start it and follow the setup wizard. The Hyper-V drivers are part of the operating system, but you have to enable them manually by editing the /etc/initramfs-tools/modules file and adding the following lines: hv_vmbus hv_storvsc hv_blkvsc hv_netvsc After saving the file, execute the update-initramfs –u command for changes to take effect and reboot the virtual machine. To verify that the drivers are l

Microsoft Exchange Message Export and Import

I had faced a strange Microsoft Exchange issue last week, messages were getting stuck in the submission queue of an Exchange 2010 SP3 Hub Transport server possibly due to an issue on the Transport Rule Agent. While troubleshooting the issue, since there were a lot of messages in the queue, around two thousands, I decided to export them and import them on the second Hub Transport server. In order to export the messages I used the following command: 1 2 3 4 5 6 7 8 9 10 $messages = Get-Message -Queue "EXCHANGESERVER\Submission" ForEach ( $m in $messages ) { $Temp = "C:\Messages\" + $m .InternetMessageID + ".eml" $Temp = $Temp .Replace( "<" , "_" ) $Temp = $Temp .Replace( ">" , "_" ) $Temp = $Temp .Replace( "\\" , "_" ) Export-Message $m .Identity | AssembleMessage -Path $Temp }  I used the Get-Message cmdlet to get all t

How to Setup Exchange Email Forwarding using Powershell

There have been many times when a request came in order to forward messages sent a mailbox to another mailbox or mailcontact. This mostly happens when there is an ongoing migration and the user has an account on the other organization that is part of the migration, or they just want their mail to be forwarded to another account in order for them to not have to check multiple mailboxes. But let's cut to the chase! Every mailbox has two properties, ForwardingSMTPAddress and DeliverToMailboxandForward. The ForwardingSMTPAddress is the address where the messages are going to be forwarded. The DeliveToMailboxandForward is the option to leave a copy of the message to the mailbox. So, if you want to just forward the messages sent to user John Smith to john.smith@otherorg.com, you should use: 1 2 Set-Mailbox -Identity "John Smith" ` -ForwardingSMTPAddress "john.smith@otherorg.com.net" 1 2 3 Set-Mailbox -Identity "John Smith" `

Exchange Server Export Mailboxes of Disabled Users

I was asked the other day to get a list of all the mailboxes connected to users disabled on Active Directory. I fired up Powershell ISE, loaded the Active Directory module and the Exchange snap-ins and started to work on my script. First of all, I had to get a list of all the users in Active Directory that were disabled. This is very easy to implement using the Get-ADUser cmdlet and the Filter parameter. The company's Identity Management System though when disabling a user, it also moves the object to specific OU named "Disabled". To get those users I used the Get-ADUser cmdlet with the SearchBase and filter paramaters: 1 2 $users = Get-ADUser -SearchBase "OU=DISABLED, DC=LAB, DC=LOCAL" -Filter * -Properties * | Where-Object { $_ .enabled -eq $false } Just to make sure that I do not include any active users, I piped the output to a Where-Object cmdlet. Now that I have all the users I had to check if they had a mailbox. Since the

Microsoft SQL Linked Server Test

Today's topic? Microsoft SQL Server Linked Servers! Linked Servers are objects created in Microsoft SQL Server that allow queries to access data on other database servers such as Oracle. There are many reasons why a query that uses a linked server may fail with driver and network being the most common ones. When I need to troubleshoot scenarios like the above, I usually start with testing the linked server connectivity with the query below. 1 2 3 4 5 6 7 8 9 10 declare @ srv nvarchar( 128 ), @ retval int ; set @ srv = ‘ my_linked_server ' ; begin try exec @ retval = sys.sp_testlinkedserver @ srv; end try begin catch set @ retval = sign( @@ error); end catch; if @ retval <> 0 raiserror( ‘ Failed to connect to server ! ’ , 16 , 2 );

NetScaler InSight Center Authentication Delegation

Image
Whenever I'm called to setup or troubleshoot Citrix NetScaler performance issues, I try to bring Citrix InSight Center into the game. InSight Center is a Linux based Virtual Machine which gathers AppFlow performance data from the NetScaler thus helping with performance troubleshooting. I am not a fan of local user accounts on any system for many reasons, so I'll show you how to delegate the user authentication of the InSight Center to Active Directory. Let's start with logging on to the InSight Center using the default administrator account "nsroot" and navigating to the "Authentication" node under "System". Here we see all the available authentication methods supported: RADIUS, LDAP and TACACS. Since we want to delegate the authentication to Active Directory, we're interested in LDAP. Select the "LDAP" methods, and then click "Add" to add a server. Fill in the IP address of a domain controller (or a Load Bal

Powershell Event Log Filtering

I run across a fairly old Powershell script today that I had to use in order to get some information from the Security log of a Domain Controller. The domain controller has been around for a long time and the log was a bit large. I run the script once and it took forever to complete so I decided to take a look under the hood... First of all the script was using the Get-EventLog cmdlet which isn't the best thing... I examined the script for the event id's of the entries we would like to get and then I replaced the Get-EventLog and Where-Object cmdlets with the Get-WinEvent and the XML filter for the events. You may wonder, how are we going to build the XML filter for the WinEvent? Well, I'll show you a little trick. First we open Event Viewer, select the log and then select "Filter Current Log". A window will pop up and you'll have to fill the necessary fields. Wait, don't hit "OK" yet, switch to the XML tab and copy the query text. Nex

Powershell Property Rename

Image
When using Powershell, we sometimes have to change the names of the properties returned by a cmdlet. There are many reasons for doing this, take exporting data as an example. You want to export an array of objects and set custom property names in order to format it as requested. Another important reason for changing the name of a property it passing objects down the pipeline. When using the pipeline, the property may be named differently that the parameter name for the next command. You'll run into this kind of problems when using cmdlets from differents modules like ActiveDirectory and Exchange. A property may be named "ComputerName" for an AD cmdlet and "Server" for an Echange cmdlet. Let's see what you can do about it... For example, we want to test network connectivity on port 389 towards all domain controllers. First we will get the list of the domain controllers using the cmdlet Get-ADDomainController and then we will test connectivity using Tes

Windows Server 2012 R2 Evaluation Upgrade

Image
Sometimes you just have to fire up a Windows Server system in order to test something and if you're like me, you'll create a new virtual machine for this purpose. Most of the times, I create a VM using an evaluation copy of Windows Server since the evaluation period is more than enough and the client may not have the necessary license. There are times however when I had to license an evaluation copy! So, let's cut to the chase! I used the DISM tool to get the current edition of the OS and the supported target editions and perform the upgrade. Start by opening an elevated Powershell window and run the command: dism /online /get-currentedition   From the output you can see that the server is running ServerStandardEval edition.   Let's get the supported upgrade editions by running:   dism /online /get-targeteditions     and since ServerDatacenter is supported, will upgrade to that using:   dism /online /set-edition:serverdatacenter

Powershell COM Object Disposal

I run into a strange issue with one of my Powershell scripts the other day, I was using an Excel COM object and I had an Excel process even after calling the objects Quit() function. All the script was doing was to open an Excel xlsx file and save it as csv file. I could use the Get-Process and Stop-Process cmdlets be I would like to be able to schedule the script to run and not be afraid that it would kill any other Excel processes running at the same time. After a few searches I found out that I could release the COM object with the following command: [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) Here we are releasing the COM object excel using the Interopservices. Before doing this, make sure that you have saved your work done using the COM object.

Windows 2012 R2 and Windows 8.1 Partition Resize

Unlike on their predecessors, on Windows Server 2012 R2 and Windows 8.1 (and later), you can resize the system partition online without having to shut the OS down. And since I've got a thing for Powershell, I'll suggest a couple of cmdlets that will get the job done. First of all, you have to make sure that there is unpartitioned space on the disks. In most cases you'll be expanding a virtual machine's partition so you'll have to resize the virtual disk first. The cmdlet we're going to use is Resize-Partition and you can find the definition here.  Before we start resizing we have to identify the disk number of the disk and the partition number. The Get-Disk cmdlet will help you with the disk numbers and the Get-Partition with the partition number. When you have the partition and disk number, you have to decide the new partition size and you're ready to resize. If you want the partition to take up all the free space left on the disk, you can use th

Dell OMSA Installation on Windows Server Core

Dell has been very popular over the last few years regarding servers and now storages (after EMC take over) so I'm sure that many of you will have to install Dell OpenManage System Administrator (OMSA) on your systems. I recently had to install it on a Core installation of Windows Server 2012 R2. Although I'll describe the process, there's a small detail that you'll have to remember if you do not want to waste an hour like me. So, first things first, you have to check if the WOW feature is installed on the server. You can use powershell to do this using the Get-WindowsFeature -Name *wow* command. If it is not installed you can install it using Powershell Add-WindowsFeature or the following command: dism /online /enable-feature /featurename:ServerCore-WOW64 After downloading the appropriate OMSA installation file for your server version to your server (I usually create a folder named "Dell" in C:), you have to run the executable to extract the files.

MySQL Export Table to CSV

I was recently assigned the task to export a MySQL table to a file in CSV format, so I was time to brush my Linux and MySQL skills.. After a little research I managed to get things done using the following command: mysql -uroot -ptoor -e "SELECT * from tablename" databasename | sed 's/\t/","/g;s/^/"/;s/$/"/' > filename.csv I am using the mysql tool to connect to the database "databasename" using root as username and toor as password. Pay attention here, the root is the MySQL root user, not the OS user! After executing the query to get all the records from the table "tablename" I pipe the output to the sed utility to add the delimiters. In the last step, the output is redirected to the file we want to contain the table.

VMware Import Error

I exported a VM from an ESXi host yesterday and I tried to import it to a cluster but I got the following error: "OVF Deployment Failed: File ds:///vmfs/volumes/ uuid /_deviceImage-0.iso was not found" This happened because I had connected an .iso file to the CD/DVD device and that file was not available on the destination host. To overcome this issue you may edit the .ovf file created by the export process and replace the "vmware.cdrom.iso" to "vmware.cdrom.remotepassthrough" option. The tricky part now, when you edit the file, the checksum of the file is changed so you have to update it on the .mf file created also be the export process. Get the file's SHA1 checksum using your favourite tool and set it in the .mf file. Then, you're good to go, you should be able to import the VM without any problems. As a final note, I would suggest you made backup copies of the two files above in order to avoid exporting the VM again. Documented o