Category Archives: PowerShell

How to manage vmware ESX with PowerShell

  1. Prerequisites:
    • Windows .Net Framework 2.0 (3.5 latest SP Recommended).
    • Windows PowerShell (V2 Recommended).
  2. Install vSphere client.
  3. Set the ‘Execution Policy’ of PowerShell to Remote Signed.
    • Run PowerShell as administrator.
    • Set-ExecutionPolicy RemoteSigned
  4. Type Exit and press Enter to leave the PowerShell prompt.
  5. Do it on both PowerShell consoles: x86 and x64.
  6. Download the PowerCLI software to your workstation from the following URL: http://vmware.com/go/PowerCLI
  7. Run the PowerCLI exe file.
  8. Install it all the way with default values. Click next until you arrived to finish screen and click finish.
  9. On your desktop you will now have two icons, which allow you to launch PowerCLI, a 64 bit version and a 32 bit version.
  10. Copy the PowerCLI modules folder to the PowerShell modules folder:
  11. C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Modules -> C:\Windows\System32\WindowsPowerShell\v1.0\Modules
  12. View the new vmware modules: Get-Module -ListAvailable | ? {$_.name -like “*VMware*”}
  • Example

C:\WINDOWS\system32> Get-Module -ListAvailable | ? {$_.name -like “*VMware*”}

    Directory: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PowerCLI\Modules

ModuleType Version    Name                                ExportedCommands

———- ——-    —-                                —————-

Binary     6.0.0.0    VMware.DeployAutomation

Binary     6.0.0.0    VMware.ImageBuilder

Binary     6.5.0.4… VMware.VimAutomation.Cis.Core

Binary     6.5.0.4… VMware.VimAutomation.Cloud

Manifest   6.5.0.4… VMware.VimAutomation.Common

Binary     6.5.0.2… VMware.VimAutomation.Core           HookGetViewAutoCompleter

Binary     6.0.0.0    VMware.VimAutomation.HA

Binary     7.0.2.4… VMware.VimAutomation.HorizonView

Binary     6.5.0.4… VMware.VimAutomation.License

Binary     6.5.0.4… VMware.VimAutomation.PCloud

Manifest   6.5.0.4… VMware.VimAutomation.Sdk            Get-PSVersion

Binary     6.5.0.4… VMware.VimAutomation.Storage

Binary     6.5.0.4… VMware.VimAutomation.Vds

Binary     6.5.0.4… VMware.VimAutomation.vROps

Binary     6.0.0.0    VMware.VumAutomation

  1. Import the modules you need: Import-Module -Name VMware.VimAutomation.Core
  2. The end.

Source: Back to Basics: Part 1 – Installing PowerCLI – VMware PowerCLI Blog – VMware Blogs

https://blogs.vmware.com/PowerCLI/2015/03/powercli-6-0-introducing-powercli-modules.html

how to Search-Keywords in files – PowerShell function

function Search-File{
PARAM(
[STRING[]]$Path = $pwd,
[STRING[]]$Include = “*.ps1”,
[STRING[]]$KeyWord = (Read-Host “Keyword?”),
[SWITCH]$ListView
)

<#
Descrition: This function allows you to search a folder and it’s sub directories for files containing a keyword.

Exampls: Search-File -Path C:\temp -Include “*.pdf” -KeyWord “nagios”

Date: Sunday, April 3, 2016 10:03:16 AM

The function uses three parameters and one switch.

Parameters

-Path
By default, the path will use your present working directory ($pwd). The search path is always recursive.

-Include
By default the include is set to “*.ps1”. The value for this parameter filters by file name.
Examples : -Include “*.log” or “Servers*.log”

-Keyword
If no value is provided you will be prompted with “Keyword?:”.
This parameter invokes “Search-String -Simplematch $Keyword”; I sometimes search for regular expressions, but a switch could be added to the function to utilize “Search-String -Pattern” allowing use of regular expressions in the keyword search.
Uses a simple match rather than a regular expression match. In a simple match, Select-String searches the input for the text in the Pattern parameter. It does not interpret the value of the Pattern parameter as a regular expression statement.

Switches

-ListView
While the default formatting neatly groups matched lines under the filename, the line is truncated. If you want to see the full line containing the match, use this switch.

#>

Get-ChildItem -path $Path -Include $Include -Recurse | `
sort Directory,CreationTime | `
Select-String -simplematch $KeyWord -OutVariable Result | `
Out-Null

IF ($ListView) {
$Result | Format-List -Property Path,LineNumber,Line
}
ELSE {
$Result | Format-Table -GroupBy Path -Property LineNumber,Line -AutoSize
}

}

Source: Search-Scripts – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

Add PowerShell to Windows Explorer Context Menu in Windows 10

Here’s a quick tutorial on how to add PowerShell to the Windows Explorer context menu in Windows 10.

Source: Add PowerShell to Windows Explorer Context Menu in Windows 10 – Petri

1. Open the Registry Editor. You can do this by clicking on Start and typing regedit.

2. Navigate to the following path:

HKEY_CLASSES_ROOT\Directory\Shell

Create a new key by clicking Edit > New > Key.

Call the new key “PowerShell.”

3. Modify the default string in the “PowerShell” key by right-clicking it and selecting “Modify…”

Call the new value “Open PowerShell Here.” Click “OK.

4. In the PowerShell key, create a new key by clicking Edit > New > Key.

5. Call the new key “command.”

6. Modify the default string in the command key by using the following text:

C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command Set-Location -LiteralPath ‘%L’

Click “OK.”

7. Add a new string by clicking Edit > New > String value.

Let’s call it “Icon.”

8. Modify the value by using the following text:

“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”,0

Click “OK.”

9. After completing these steps, close the registry, and open Windows Explorer. Go to any folder of your choice and right-click the folder

 

 

 

 

Process Monitoring with PowerShell

PowerShell MVP Jeff Hicks shares his script for watching processes using a WMI event subscription using the CIM cmdlets.

Source: Process Monitoring with PowerShell – Petri

$Poll = 120 #check the computer every two minutes

<#
I want to select all properties from the WMI class called CIM_InstModification.
This is a special system class that’s triggered when an object is modified.
I don’t want to find every object, as it is changed every second. So I tell WMI to check within a time frame of seconds.
When this event fires, WMI will have a new object called the TargetInstance.
This will be the changed object, and I only care about those that are Win32_Process objects.
The ISA operator accomplishes that.
The last part of the query is to limit results to those process objects, which is what the TargetInstance is, with a WorkingSetSize property of greater or equal to 500 MB.
#>

$query = “Select * from CIM_InstModification within $Poll where TargetInstance ISA ‘Win32_Process’ AND TargetInstance.WorkingSetSize>=$(1000MB)” #WMI query

<#
When you create the event subscriber, you can choose to simply record the events in your PowerShell session as matching events are detected.
Or you can take action.
In my case, I want to do a few things everytime a matching process is found.
I want to create a log file, and I want to display a popup message.
#>

$action={
#create a log file
$logPath= “C:\Work\HighMemLog.txt”
“[$(Get-Date)] Computername = $($Event.SourceEventArgs.NewEvent.SourceInstance.CSName)” | Out-File -FilePath $logPath -Append -Encoding ascii
“[$(Get-Date)] Process = $($Event.SourceEventArgs.NewEvent.SourceInstance.Name)” | Out-File -FilePath $logPath -Append -Encoding ascii
“[$(Get-Date)] Command = $($Event.SourceEventArgs.NewEvent.SourceInstance.Commandline)” | Out-File -FilePath $logPath -Append -Encoding ascii
“[$(Get-Date)] PID = $($Event.SourceEventArgs.NewEvent.SourceInstance.ProcessID)” | Out-File -FilePath $logPath -Append -Encoding ascii
“[$(Get-Date)] WS(MB) = $([math]::Round($Event.SourceEventArgs.NewEvent.SourceInstance.WorkingSetSize/1MB,2))” | Out-File -FilePath $logPath -Append -Encoding ascii
“[$(Get-Date)] $(‘*’ * 60)” | Out-File -FilePath $logPath -Append -Encoding ascii

#create a popup
$wsh = New-Object -ComObject Wscript.shell
$Title = “$(Get-Date) High Memory Alert”
$msg = @”
Process = $($Event.SourceEventArgs.NewEvent.SourceInstance.Name)
PID = $($Event.SourceEventArgs.NewEvent.SourceInstance.ProcessID)
WS(MB) = $([math]::Round($Event.SourceEventArgs.NewEvent.SourceInstance.WorkingSetSize/1MB,2))
“@

#timeout in seconds. Use -1 to require a user to click OK.
$Timeout = 10
$wsh.Popup($msg,$TimeOut,$Title,16+32)

}

#Now that I have the action scriptblock all that remains is to register the subscription with the Register-CimIndicationEvent.#
Register-CimIndicationEvent -Query $query -SourceIdentifier “HighProcessMemory” -Action $action

#You can see the registration with the Get-EventSubscriber cmdlet.
#This subscription will run for as long as my PowerShell session is running.
#The corollary is that I will need to recreate it every time I want to start monitoring.
#If this is a daily task, I could put it in my PowerShell profile script.

#If you want to get rid of the subscriber, simply unregister it.
#Get-EventSubscriber -SourceIdentifier “HighProcessMemory” | Unregister-Event

 

Manage Office 365 Forward Mail in PowerShell

Manage Forward Mail by using PowerShell | Office 365

<#

this script set Automatic mail Forwarding to Recipient in office 365

#>

#start script

##########################

#$user=’internal user idestity’ #the source internal user to forward emails from
#$destemail=’internal user email destination address’ #internal destination user to forward emails to
#$destemailext=’xxx@gmail.com’ #external destination email address to forward emails to
#$DisplayName’MailContact Display Name’ #MailContact Display Name
#$mailintext=’Office 365 User Email ‘ #<Office 365 User Email Address for external user (MailContact)

##########################

#Connect to Exchange Online Office 365 using remote PowerShell
#$UserCredential = Get-Credential
#$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
#Import-PSSession $Session

##########################

#Forward Email to internal Recipient & DONT saves local copy
#Set-Mailbox $user -ForwardingAddress $destemail -DeliverToMailboxAndForward $False

##########################

#Forward Email to internal Recipient & save local copy (Default)
#Set-Mailbox $user -ForwardingAddress $destemail

##########################

#Forward Email to External Recipient & save local copy (Default)
#Set-Mailbox $user -ForwardingsmtpAddress $destemailext

##########################

#Forward Email to External Recipient & DONT saves local copy
#Set-Mailbox $user -ForwardingsmtpAddress $destemailext -DeliverToMailboxAndForward $False

##########################

#Create External contact with internal email address + Forward email address (External Email Address)
#Step 1: Create External contact with External email address
#New-MailContact -Name $DisplayName -ExternalEmailAddress $destemailext
#Step 2: Set External contact email address to internal email address and forwarding email address (External email address) PowerShell command syntax:
#New-MailContact $DisplayName -emailaddresses SMTP:$mailintext, $destemailext

##########################

#Display information about Forwarding rule
#Get-Mailbox $user

##########################

#Display more information about Forwarding rule
#Get-Mailbox John | FL DeliverToMailboxAndForward,ForwardingAddress,ForwardingSmtpAddress

##########################

#Find all users with Forwarding Address is set to Internal Recipient
#Get-Mailbox | Where {$_.ForwardingAddress -ne $Null} | Select Name, ForwardingAddress, DeliverToMailboxAndForward

##########################

#Turn off Email Automatic Forwarding to internal Recipient
#Set-Mailbox $user -ForwardingAddress $Null

##########################

#Turn off email Automatic Forwarding to External Recipient
#Set-Mailbox $user -ForwardingSmtpAddress $Null

##########################

#Forward Email of ALL Users to internal Recipient & save local copy
#Step 1: Save local copy
#Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”}| Set-Mailbox -DeliverToMailboxAndForward $True
#Step 2: Forward email to the destination recipient (internal\organization recipient)
#Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”}| Set-Mailbox -ForwardingAddress $destemail

##########################

#Forward Email of ALL Users to External Recipient & save local copy
#Step 1: Save local copy
#Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”}| Set-Mailbox -DeliverToMailboxAndForward $True
#Step 2: Forward email to the destination recipient (external recipient)
#Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”}| Set-Mailbox -ForwardingSmtpAddress $destemailext

##########################

#Turn off email Automatic Forwarding to External Recipient
#Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”}| Set-Mailbox -ForwardingAddress $Null

##########################

#verify that the email is set to forword
#Get-Mailbox $user| FL DeliverToMailboxAndForward,ForwardingAddress,ForwardingSmtpAddress

##########################

#end Exchange Online Office 365 remote PowerShell Session
#Remove-PSSession $Session

#end script

Search WMI for Useful Information in  PowerShell

Search WMI for Useful Information

Source: Search WMI for Useful Information – Power Tips – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

<#

WMI is a great source of information, but it is not always easy to find out the names of valid WMI classes to query.

Here is a little search tool: it asks for a keyword, then searches WMI for all valid classes with this keyword. The results are shown in a grid view window, and when you choose a class and press OK, the tool queries the class for you, showing the results:

#requires -Version 3

#>

function Search-WMI
{
param([Parameter(Mandatory=$true)]$Keyword)

Get-WmiObject -Class “Win32_*$Keyword*” -List |
Where-Object { $_.Properties.Count -gt 6 } |
Where-Object { $_.Name -notlike ‘Win32_Perf*’ } |
Sort-Object -Property Name |
Select-Object -Property @{Name=’Select one of these classes’; Expression={$_.Name }} |
Out-GridView -Title ‘Choose one’ -OutputMode Single |
ForEach-Object {
Get-WmiObject -Class $_.’Select one of these classes’ | Out-GridView
}
}

<#

Example:

Search-WMI -Keyword network

#>

how to Output File Sizes in Different Formats in PowerShell

Access free scripts, daily tips, and videos to help you master Windows Powershell. Get expert advice from DR. Tobias Weltner, Poweshell MVP. Free Membership!

Source: Outputting File Sizes in Different Formats – Power Tips – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

<#

When you store a number in a variable, you may want to display the number in different units. Bytes are very precise, but sometimes displaying the bytes as kilobytes or megabytes would be more appropriate.

Here is a clever trick that overwrites the internal ToString() method with a more versatile one: it takes a unit, the number of digits you want, and the text of a suffix. This way, you can display the number in various formats, just as needed.

The content stays untouched, so the variable still holds an integer value that you can safely sort or compare to other values:

#requires -Version 1

#>

$a = 1257657656
$a = $a | Add-Member -MemberType ScriptMethod -Name tostring -Force -Value { param($Unit = 1MB, $Digits=1, $Suffix=’ MB’) “{0:n$Digits}$Suffix” -f ($this/($Unit)) } -PassThru

<#

And here are some examples on how you can use $a now:
PS> $a
1.199,4 MB

PS> $a.ToString(1GB, 0, ‘ GB’)
1 GB

PS> $a.ToString(1KB, 2, ‘ KB’)
1.228.181,30 KB

PS> $a -eq 1257657656
True

PS> $a -eq 1257657657
False

PS> $a.GetType().Name
Int32

#>

how to Convert Date/Time Formats in PowerShell 

Converting Date/Time Formats

Source: Converting Date/Time Formats – Power Tips – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

#Here is a simple PowerShell filter that can convert any DateTime object into any date/time-format you like:

#requires -Version 1

filter Convert-DateTimeFormat
{
param($OutputFormat=’yyyy-MM-dd HH:mm:ss fff’)

try {
([DateTime]$_).ToString($OutputFormat)
} catch {}
}

<#
And here are some examples on how to run it:
PS> Get-Date | Convert-DateTimeFormat
2015-10-23 14:38:37 140

PS> Get-Date | Convert-DateTimeFormat -OutputFormat ‘dddd’
Friday

PS> Get-Date | Convert-DateTimeFormat -OutputFormat ‘MM”/”dd”/”yyyy’
10/23/2015

PS> ‘2015-12-24’ | Convert-DateTimeFormat -OutputFormat ‘dddd’
Thursday

As you see, you can pipe into Convert-DateTimeFormat anything that either is a DateTime object already, or can be turned into one. By default, the function displays the ISO format for it, but with -OutputFormat you can specify your own format as well.

When you look at the source code, you can see the letters that resemble date and time components. Note that these are case-sensitive (“m” represents a minute, whereas “M” represents a month), and the more of them you specify, the more detailed will that information be displayed.

Anything you want to appear as literal text needs to be included in quotes.
#>

How To Copy Command History to the clipboard in PowerShell

Copying Command History

Source: Copying Command History – Power Tips – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

You can copy your entire command history to the clipboard:

(Get-History).CommandLine | clip.exe 

This technique uses automatic unrolling introduced in PowerShell 3.0. To use it in PowerShell 2.0, you would have to manually expand the CommandLine property like this:

Get-History | Select-Object -ExpandProperty commandline | clip.exe 

To copy only the last five commands, simply add the -Count parameter to Get-History:

(Get-History -Count 5).CommandLine | clip.exe

How To Find Process Owner With PowerShell

Get-Process gets you a list of all running processes, but it will not reveal the process owner. To find the process owner, you would need to ask the WMI service, for example.

To make this easier, here is a little helper function:

filter Get-ProcessOwner
{
  $id = $_.ID
  $info = (Get-WmiObject -Class Win32_Process -Filter "Handle=$id").GetOwner()
  if ($info.ReturnValue -eq 2)
  {
    $owner = '[Access Denied]'
  }
  else
  {
    $owner = '{0}\{1}' -f $info.Domain, $info.User
  }
  $_ | Add-Member -MemberType NoteProperty -Name Owner -Value $owner -PassThru
}

When you pipe process objects into Get-ProcessOwner, it appends a new property called “Owner” to the process object. This property is hidden unless you ask Select-Object to show it:

 
PS> Get-Process -Id $pid | Get-ProcessOwner | Select-Object -Property Name, ID, Owner

Name                    Id Owner                    
----                    -- -----                    
powershell_ise       10080 TOBI2\Tobias 

This works for multiple process objects as well:

 
PS> Get-Process | Where-Object MainWindowTitle | Get-ProcessOwner | Select-Object -Property Name, ID, Owner

Name                    Id Owner                    
----                    -- -----                    
chrome               13028 TOBI2\Tobias             
devenv               13724 TOBI2\Tobias             
Energy Manager        6120 TOBI2\Tobias             
ILSpy                14928 TOBI2\Tobias             
(...)

Note that you get process owners only when you have Administrator privileges. Without these privileges, you can get the owner only for your own processes, which is relatively pointless.

Finding Process Owner – Power Tips – PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources.