Tuesday, April 2, 2013

Exchange PowerShell Commands

It's been a long time between drinks...

However, I have still been quietly squirreling away useful command lines, with the following 166 commands used for Exchange 2007/2010 information gathering, automating configuration management, troubleshooting and many bits in between.

Each command can be copied and pasted into a PowerShell command line running the Exchange snap-in loaded with the default prefix, although you may need to adjust input such as distinguished names, server names, mailbox names etc.

Let me know if you find them useful.

Get mailboxes that have a space in the displayName
get-mailbox -filter "(displayname -like '* *')" | ft identity,database -wrap -auto

Find Exchange transport rules
Get-TransportRule | ft Name,Priority,{$_.Conditions | select Name,{$_.Words}},{$_.Actions | select Name,Rank,SclValue},Comments -wrap -auto 

Find Exchange 2007 mailbox servers in the local organisation

Get mailbox statistics for mailbox servers with the specified name
get-mailboxserver | where {$_.Name -like 'server*'} | Get-MailboxStatistics | Sort-Object TotalItemSize -Descending | select-object -prop DisplayName,LastLogonTime,StorageLimitStatus,TotalItemSize,TotalDeletedItemSize,@{N="Size (MB)";E={$_.TotalItemSize.Value.ToMB()}},@{N="Deleted Item Size (MB)";E={$_.TotalDeletedItemSize.Value.ToMB()}},ItemCount,ServerName,StorageGroupName,DatabaseName.LegacyDN | export-csv -path c:\temp\MailboxStatistics.csv

Get mailbox database size limit/quota settings on malibox stores
get-mailboxdatabase | select-object -prop Name,ServerName,StorageGroup,ProhibitSendReceiveQuota,ProhibitSendQuota,IssueWarningQuota | ft -wrap -autosize

Find the number of mail-enabled contacts in the organisation
get-mailcontact -ResultSize 'unlimited' | measure

Export the IP addressed allowed to relay through the specified connector
$rc = Get-ReceiveConnector -id 'server01\connector01'; $rc.RemoteIPRanges | export-csv -path c:\temp\rc1.csv

Exchange 2007 global transport size limits
get-transportconfig | ft -prop MaxReceiveSize,MaxSendSize -wrap -autosize   

Exchange 2007 transport server sizelimits
get-transportserver | ft -prop Name,OriginatingServer,InternalDsnMaxMessageAttachSize,ExternalDsnMaxMessageAttachSize -wrap -autosize

Exchange 2007 send connector size limits
get-sendconnector | ft -prop Identity,AddressSpaces,MaxMessageSize -wrap -autosize

Exchange 2007 receive connector size limits
get-receiveconnector | ft -prop Identity,AddressSpaces,MaxMessageSize -wrap -autosize

Exchange 2007 mailbox limits other than unlimited
get-mailbox |where {$_.MaxSendSize -ne 'unlimited' -or $_.MaxReceiveSize -ne 'unlimited'} | ft -prop Identity,MaxSendSize,MaxReceiveSize -wrap -autosize

Get the storage group copy status (CCR/LCR/SCR) for mailbox stores 
get-mailboxserver | where {$_.Name -like 'server*'} | Get-StorageGroupCopyStatus  | ft -wrap -autosize

Get storage groups and their SCR stand-by machine
Get-StorageGroup  | ft -prop Name,Server,StandbyMachines -wrap -autosize

Get the storage group copy status (SCR) for the first target on all SGs
Get-StorageGroup | %{Get-StorageGroupCopyStatus -id $_.Identity -StandbyMachine $_.StandbyMachines[0].NodeName} | sort -prop LastReplayedLogTime | select -prop Identity,SummaryCopyStatus,ServiceDown,CopyQueueLength,ReplayQueueLength,LatestAvailableLogTime,LastCopyNotificationedLogTime,LastCopiedLogTime,LastInspectedLogTime,LastReplayedLogTime,LatestFullBackupTime | export-csv -path c:\temp\SCR_Status.csv

Get the storage group copy status (SCR) for the specified server/target
Get-StorageGroupCopyStatus -Server server01 -standbymachine server01 | ft -wrap -autosize

Find the backup status and whether VSS was used for the backup
Get-StorageGroup | %{Get-StorageGroupCopyStatus -id $_.Identity -StandbyMachine $_.StandbyMachines[0].NodeName} | sort -prop LatestFullBackupTime | select -prop Identity,SummaryCopyStatus,ServiceDown,LatestFullBackupTime,SnapshotBackup  | export-csv -path c:\temp\MailboxBackup_Status.csv

Change an Exchange 2007 mailbox type to equipment (or room)
Set-Mailbox MailboxName -Type Equipment

Add full access mailbox permissoins for an Exchange 2007 mailbox
Add-MailboxPermission -Id MailboxName -User:'DOMAIN\group' -AccessRights:FullAccess

Add send as rights to the AD security of a mail-enabled user
Add-ADPermission -Id MailboxName -User:'DOMAIN\group' -ExtendedRights:Send-As

Find mailboxes that are not standard user mailboxes (Room, Equipment)
get-mailbox | where {$_.RecipientTypeDetails -ne 'UserMailbox'} | fl -prop Name,RecipientTypeDetails

Remove mailbox permissions for the specified user
Remove-MailboxPermission MailboxUser -User DOMAIN\User -AccessRight FullAccess    

Find exchange mailbox statistics including per-user mailbox and DB limits 
. C:\data\scripts\PowerShell\Exchange\FindMailboxSizes.ps1 | out-file -file c:\temp\MailboxStats.txt -encoding ascii

Find the AutomateProcessing setting for a resource mailbox
Get-MailboxCalendarSettings  -id mailboxID

Modify a resource mailbox to automatically accept in-policy requests
Set-MailboxCalendarSettings -id mailboxID -AllBookInPolicy:$true 

Find the mailbox type of one or more mailboxes
get-mailbox -id mailboxes* | fl -prop IsResource,RecipientType,RecipientTypeDetails,ResourceType

Find the debug event logging levels set on an Exchange 2007 server
Get-EventLoglevel -server ExchangeServer01

Set the equipment mailbox to auto-accept and allow anyone to automatically book
Set-MailboxCalendarSettings -Identity "mailbox01" -AutomateProcessing AutoAccept -AllBookInPolicy $true

Turn on high logging for the booking attendant
Set-EventLogLevel "server01\MSExchangeMailboxAssistants\Resource Booking Attendant" -Level High

Find all resource mailboxes of type equipment
get-mailbox |where {$_.resourcetype -eq 'Equipment'}

Read Exchange 2007 event logs for the MSExchangeMailboxAssistants (resources)
get-eventlog -logname application -computer server01 -source msexchangemailboxassistants

Check Exchange Message Tracking Logs based on message ID
Get-MessageTrackingLog -MessageId '' -Start "05/07/2011 00:00:00" -End "07/07/2011 06:00:00" -server server01

Check Exchange Message Tracking Logs based on mail subject
Get-MessageTrackingLog -MessageSubject "RE: Subject" -Start "06/07/2011 00:00:00" -End "07/07/2011 00:00:00" -server server01

Find Exchange server version, edition and roles
Get-ExchangeServer | sort | select-object -prop Name,Role,Edition,ServerRole,Site,ExchangeVersion,AdminDisplayVersion | export-csv -path c:\temp\ExchangeServers.csv

Find the mailbox sizes in Exchange 2007 looking at the filesystem
Get-MailboxDatabase | foreach-object {add-member -inputobject $_ -membertype noteproperty -name mailboxdbsizeinGB -value ([math]::Round(([int64](get-wmiobject cim_datafile -computername $_.server -filter ('name=''' + $_.edbfilepath.pathname.replace("\","\\") + '''')).filesize / 1GB),2)) -passthru} | Sort-Object mailboxdbsizeinGB -Descending | format-table identity,mailboxdbsizeinGB 

Update the allowed IP addresses for an Exchange 2007 receive connector
$connector = Get-ReceiveConnector -id 'server01\connector01'; $connector.RemoteIPRanges += ""; Set-ReceiveConnector 'server01\connector01' -RemoteIPRanges $connector.RemoteIPRanges

Move a mailbox to a new database
Move-Mailbox -id user01 -targetdatabase 'server01\sg01\db01' 

View the original warning quota message
Get-SystemMessage -original | where {$_.Identity -like 'en\warn*'}

Add a new warning quota message
New-SystemMessage -QuotaMessageType WarningMailbox -Language EN -Text "Please reduce your mailbox size! Delete any items you don't need from your mailbox and empty your Deleted Items folder."

Hide a mailbox from the GAL
get-mailbox -id user01 | set-mailbox -HiddenFromAddressListsEnabled:$true

Remove SID History from a user
get-aduser -id 'user01' -prop sIDHistory | foreach {set-aduser $_ -remove @{sIDHistory=$_.sIDHistory.value}}

Remove SID history from one or more groups
Import-Module ActiveDirectory; $groups = get-content -path groups_sAMAccountName.txt; foreach ($group in $groups) {get-adgroup -id $group -prop sIDHistory | foreach {set-adgroup $_ -remove @{sIDHistory=$_.sIDHistory.value}}}

Remove multiple attributes from an AD account
$user = get-aduser -id 'user01' -prop HomeDrive,HomeDirectory,ProfilePath; set-aduser $user -HomeDrive $null -HomeDirectory $null -ProfilePath $null

Enumerate public folders
Get-PublicFolder -server server01 -Recurse | ft -wrap -autosize

Restore a deleted user account using AD recycle bin
$deletedaccount = get-adobject -filter 'samaccountname -eq "user01"' -IncludeDeletedObjects -properties *; $deletedaccount | restore-adobject

Reconnect a mailbox to an AD user account 
$user = Get-MailboxStatistics -server server01 | where {$_.displayName -eq 'User01, Test' -and $_.DisconnectDate -ne $null}; Connect-Mailbox -Identity $user.Identity -Database $user.database -User DOMAIN\user01

Group and list the mailboxes on each mailbox store 
get-mailboxdatabase -server server01 | get-mailbox | Group-Object -prop database | ft -wrap -autosize

Create new mail contacts from CSV input in Exchange 2007
$dataSet = Import-Csv -path contacts.csv; foreach ($contact in $dataset)  {  New-MailContact -ExternalEmailAddress $contact.targetaddress -Name $ -DisplayName $contact.displayName -FirstName $contact.givenName -LastName $ -OrganizationalUnit domain.local/Contacts -PrimarySmtpAddress $contact.mail}

Set the primary mail AD attribute of a newly created Exchange 2007 contact
$contacts = get-mailcontact -OrganizationalUnit 'domain.local/Contacts' | where {$_.Name -like 'test*'} ; foreach ($contact in $contacts) {  set-mailcontact -id $contact.identity -WindowsEmailAddress $contact.PrimarySmtpAddress;  $contact.HiddenFromAddressListsEnabled = $true; }

Create a new basic authenticated send connector in Exchange 2007
$pass = Read-Host "Password?" -assecurestring; $credential = new-object System.Management.Automation.PSCredential("domain\username",$pass); $cred = get-credential -Credential $credential; New-SendConnector -Name "send01" -AddressSpaces * -AuthenticationCredential $cred -SmartHostAuthMechanism BasicAuth -DNSRoutingEnabled:$false -SmartHosts smtp.local

Find users who have been delegated send on behalf of rights to a mailbox
$delegates = Get-Mailbox 'room01' | select-object GrantSendOnBehalfTo; $delegates.GrantSendOnBehalfTo.toarray()

Find NDR 5.1.4 duplicate mail addresses from Exchange application event logs 
get-eventlog -logname 'Application' -computer server01 -after "28/10/2011 8:00:00" | where {$_.eventID -eq 3029}

Replace the primary SMTP email address 
Get-Mailbox -id 'user01' | Set-mailbox -EmailAddressPolicyEnabled $false; Get-Mailbox -id 'user01' | Update-List -Property EmailAddresses -Add "SMTP:user01@domain.local" | Set-Mailbox; Get-Mailbox -id 'user01' | Set-mailbox -EmailAddressPolicyEnabled $true

Add a new secondary SMTP address 
Get-Mailbox -id 'user01' | Update-List -Property EmailAddresses -Add "smtp:user01@domain.local" | Set-Mailbox

Check Exchange 2007 queues
Get-Queue -server server01 | ft -wrap -autosize

Find the public delegates for a mailbox and then reset to a new list
Get-Mailbox -id user01 | select -expand GrantSendOnBehalfTo; Get-Mailbox -id user01 | Set-Mailbox -grantSendOnBehalfto User02,User03,User04

Export Exchange client connection statistics (online/cached mode, client ver) 
$dateshort = [DateTime]::Now.ToString("yyyyMMddhhmmss"); get-mailboxserver | get-logonstatistics | select * | export-csv -path ("c:\temp\ExchangeLogonStats_" + $dateshort  + ".csv"); write-host ("c:\temp\ExchangeLogonStats_" + $dateshort  + ".csv")

Get a mailbox from the domain sAMAccountName 
get-mailbox -id 'domain\username' | fl *

Change the sAMAccountName of a mailbox-enabled user account
get-mailbox -id 'domain\user001' | set-mailbox -samaccountname user01

Change the Name/CN/DN of a mailbox-enabled user account
get-mailbox -id 'domain\user' | set-mailbox -DisplayName "User, Test" -Name "User, Test"

Change the alias of a mailbox object
get-mailbox -id 'domain\user' | set-mailbox -alias user01

Check if a mailbox exists
if (get-mailbox -id user01 -ErrorAction SilentlyContinue) {write-host "test"}

Find the oldest and newest dates of mailbox folders
get-mailboxfolderstatistics -id user01 -FolderScope Inbox -IncludeOldestAndNewestItems

Find Exchange logs for messages that failed to deliver
Get-MessageTrackingLog  -Start "21/12/2011 6:00:00" -server server01 | where {$_.eventId -eq 'Fail'} | ft * -wrap -autosize

Find messages where delivery failed 
Get-MessageTrackingLog -EventId FAIL -Start "20/12/2011 6:00:00" -server server01 | ft TimeStamp,Source,EventID,Recipients,Sender,RecipientStatus -wrap -autosize 

See which mailboxes a user has direct permissions to access
get-mailbox -OrganizationalUnit 'domain.local/Mailboxes/Shared' | get-mailboxpermission | where {$_.user -like 'domain\user01'}

Find mailboxes that have a specified ACE set
get-mailbox -OrganizationalUnit 'domain.local/Mailboxes/Shared' | get-adpermission | where {$_.AccessRights -contains 'WriteProperty' -and $_.Properties -like 'Personal-Information'} | ft -wrap -autosize

Find active sync utilisation for mailboxes
Get-Mailbox -ResultSize:Unlimited |ForEach {Get-ActiveSyncDeviceStatistics -Mailbox:$_.Identity} |ft identity,devicemodel,LastSuccessSync,LastPolicyUpdateTime,DeviceType,DeviceID,DeviceUserAgent,LastPingHeartbeat,DeviceFriendlyName,DeviceOS,DeviceIMEI,DevicePhoneNumber

Find SMTP mail delivery failures
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -EventId FAIL -Start "01/01/2012 6:00:00" -server $ | where {$_.recipients -like '*@*' -and $_.recipients -notlike '*' -and $_.recipients -notlike 'IMCEAEX*'} | ft EventId,Source,Sender,Recipients -wrap -autosize}

Find the owner of one or more mailboxes
get-mailbox -id user01 | get-adpermission -owner | ft -wrap -autosize

Get the Exchange 2007 organisation config

Find the Exchange 2007 accepted domains (authoritative and relay)

Find logs for distribution list expansion
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -EventId EXPAND -Start "29/02/2012 17:28:00" -server $ | ft Timestamp,Sender,RelatedRecipientAddress,Recipients,RecipientStatus -wrap -autosize}

Find logs for e-mail from a specific address
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -Sender ""  -Start "29/02/2012 17:28:00" -server $ | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find logs for failed messages
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -EventId FAIL -Start "29/02/2012 17:28:00" -server $ | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find logs for messages from the last minute
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -start (Get-Date).AddMinutes(-1)  -server $ | ft Timestamp,Sender,RelatedRecipientAddress,Recipients,RecipientStatus -wrap -autosize}

Find mail attributes for a public folder
get-mailpublicfolder -id "\Folder01\SubFolder01" | fl *

Find Exchange 2007 Web Services
Get-WebServicesVirtualDirectory | fl *

Find Exchange Message Tracking messages from a particular client IP
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -resultsize unlimited -start (Get-Date).AddMinutes(-15) -server $ | where {$_.ClientIp -eq ''} | ft * -wrap -autosize}   

Report explicit OU security for OUs in the domain
$ous = dsquery ou "dc=domain,dc=local" -limit 0; $permissions = foreach ($ou in $ous) {Get-ADPermission -id $ou.replace('"','') | where {$_.IsInherited -eq $False -and $_.User -like 'DOMAIN\*'}}; $permissions | select Identity,User,Deny,{$_.ChildObjectTypes},{$_.AccessRights},{$_.Properties},{$_.InheritedObjectType} | export-csv -path c:\temp\OU_Permission_20120309.csv

Find OWA Internal/External URL configuration
Get-OwaVirtualDirectory | where {$ -eq 'owa (Default Web Site)'} | ft Server,Name,InternalUrl,ExternalUrl -wrap -autosize 

Find transport server message tracking configuraiton 
Get-TransportServer | fl Name,messagetra*

List the available event logs from a remote server
Get-EventLog -computer server01 -list

List the Exchange 2007 diagnostic logging configuration
Get-EventLogLevel -server server01 | ft -wrap -autosize

Enable connectivity logging for Exchange 2007 Edge/Hub transport servers
get-TransportServer -id server01 | set-transportserver -ConnectivityLogEnabled:$true

View messages in the queue
get-queue -server server01 | get-message -IncludeRecipientInfo | fl *

Find recipients with a filter based on department
get-recipient -filter '((Department -eq "DEPT") -and (Alias -ne $null))'

Find users that do not have the specified primary SMTP address domain
get-recipient -filter '(ObjectClass -eq "User")' -resultsize:unlimited | where {$_.PrimarySmtpAddress -notlike "*@domain.local"} | ft Identity,PrimarySmtpAddress -wrap -autosize

Export to CSV users that don't have the specified primary SMTP domain
get-recipient -filter '(ObjectClass -eq "User")' -resultsize:unlimited | where {$_.PrimarySmtpAddress -notlike "*@domain.local"} | select Identity,PrimarySmtpAddress,Department | export-csv -path c:\temp\PrimarySMTP.csv

Expand a nested distribution group, counting all mail recipients
. C:\data\scripts\PowerShell\Exchange\ExpandDL.ps1 "CN=DL01,OU=Groups,dc=domain,dc=local"       

Find the user and SID on mailbox permissions (useful when sidhistory is used)
get-mailboxpermission -id user01 | ft User,{$_.user.securityidentifier} -wrap -auto

Find mailbox enabled users with a first/last name using ActiveDirectory
$users = get-aduser -filter {givenName -like '*' -and sn -like '*' -and mailnickname -like '*'}

Find user mailbox recipients that have a first and last name set
$mailboxes = get-recipient -resultsize unlimited -filter "(firstName -like '*' -and lastname -like '*' -and Alias -like '*' -and RecipientType -eq 'UserMailbox')"; foreach ($mailbox in $mailboxes) {  $firstName = $mailbox.firstname.replace(" ", "");   $lastName = $mailbox.lastname.replace(" ", "");   $primary = $mailbox.EmailAddresses | where {$_.IsPrimaryAddress -eq $true -and $_.PrefixString -eq "SMTP"} ;   $mailSplit =  $primary.SmtpAddress.split(".@");   if ($firstName -ne $mailSplit[0] -or $lastName -ne $mailSplit[1]) {    Write-Host $primary.SmtpAddress;   }}

Find mail recipients that don't have a first or last name (shared mailboxes)
$mailboxes = get-recipient -resultsize unlimited -filter {firstName -eq $null -and lastname -eq $null -and Alias -like '*' -and RecipientType -eq 'UserMailbox'}

Find mailboxes with the specified domain name
get-mailbox -filter {emailaddresses -like '*@domain.local'}

Find mailboxes with the specified domain name as their primary address
get-mailbox -filter {emailaddresses -like '*@domain.local'} | get-mailbox | where {$_.primarysmtpaddress -like '*@domain.local'}

Find distribution lists that can be emailed externally
$dls = get-distributiongroup -resultsize unlimited -filter {Alias -ne $null -and RequireAllSendersAreAuthenticated -eq $true}

Update the accept from for a DL with a list of users
$users = "User01, Test", "User02, Test"; foreach ($user in $users) {$user = get-mailbox -id $user; if ($user) {Get-DistributionGroup -id "DL01" | Update-List -Property AcceptMessagesOnlyFrom -Add $user.distinguishedName | Set-DistributionGroup }}

Update a distribution list to allow sending only from another DL
set-distributiongroup -id dl01 -AcceptMessagesOnlyFromDLMembers dl02

Find the user accounts for mailbox recipients with first and last name 
$mail = get-user -filter {(FirstName -ne $null -and LastName -ne $null)} -RecipientTypeDetails UserMailbox,LinkedMailbox -resultsize unlimited -OrganizationalUnit "OU=Mailboxes,dc=domain,dc=local" | select FirstName,LastName,windowsemailaddress

Find users that don't conform to first.last@ email addresses
$mail = get-user -filter {(FirstName -ne $null -and LastName -ne $null)} -RecipientTypeDetails UserMailbox,LinkedMailbox -resultsize unlimited -OrganizationalUnit "OU=Mailboxes,dc=domain,dc=local" | select FirstName,LastName,windowsemailaddress

Create a new transport rule setting SCL based on subject or body text
$condition = Get-TransportRulePredicate SubjectOrBodyContains; $condition.words = "SCL=9"; $action = Get-TransportRuleAction SetSCL; $action.sclvalue = 9; New-TransportRule -name "Filter01" -Condition $condition  -Action $action

Find mailboxes configured to forward and report details
$outputFile = "c:\temp\EmailForward_" + ([DateTime]::Now.ToString("yyyyMMddhhmmss")) + ".csv"; get-mailbox -filter {forwardingaddress -ne $null} | sort -prop whenChanged -descending | select whenChanged,SamAccountName,Identity,DeliverToMailboxAndForward,ForwardingAddress, @{N='ForwarderPrimarySMTPAddress';E={$recipient = get-recipient -id $_.ForwardingAddress; if ($recipient.recipienttype -eq 'MailContact') {write-output $recipient.externalemailaddress.tostring().replace("SMTP:","")} else {write-output $recipient.primarysmtpaddress}}},@{N='RecipientType';E={$recipient = get-recipient -id $_.ForwardingAddress; write-output $recipient.recipienttype.tostring()}} | export-csv -path $outputFile; write-host $outputFile

Turn on send connector verbose logging
get-sendconnector -id 'SendConnect01' | set-sendconnector -ProtocolLogginglevel verbose

Find NDR 5.4.6 routing loops in the last day from all transport servers
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -resultsize unlimited -EventId FAIL -Start (Get-Date).AddDays(-1) -server $ | where {$_.RecipientStatus -like '*5.4.6*'} | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find email addresses that aren't using first.last
foreach ($user in $mail) { if (!($user.windowsemailaddress.tostring().tolower().contains($user.firstname.tolower().replace(' ', '') + '.' + $user.lastName.tolower().replace(' ', '') + '@'))) { write-host $user.windowsemailaddress} }

Export a mailbox to PST
export-mailbox -id user01 -PSTFolderPath c:\temp\user01.pst

Find the Exchange 2003 global restrictions in AD for envelope recipients
Get-ADObject -id "CN=Message Delivery,CN=Global Settings,CN=ORG,CN=Microsoft Exchange,CN=Services,CN=Configuration,dc=domain,dc=local" -prop msExchRecipLimit

Find the Exchange 2007/2010 global restrictions in AD for envelope recipients
Get-ADObject -id "CN=Transport Settings,CN=ORG,CN=Microsoft Exchange,CN=Services,CN=Configuration,dc=domain,dc=local" -prop msExchRecipLimit

Find the Exchange 2007 transport settings for max enveople recipients
Get-TransportConfig | fl MaxRecipientEnvelopeLimit

Update managedBy for a distribution group
get-distributiongroup -id DL01 | Set-DistributionGroup -ManagedBy "CN=user01,OU=Mailboxes,dc=domain,dc=local"

Get the offline address book update schedule 
$oab = Get-OfflineAddressBook; $oab.schedule | ft -wrap -auto

Find the offline address book server, PF database and web distribution point
Get-OfflineAddressBook | fl Server,PublicFolderDatabase,VirtualDirectories

Find the Offline Address Book virtual directory
Get-OabVirtualDirectory | ft -wrap -auto

Find the custom resource schema configuration for custom resource properties

Gather public folder statistics
$pfstats = Get-PublicFolderStatistics -server server01

Start the Exchange Management Shell from a standard powershell instance
add-pssnapin  Microsoft.Exchange.Management.PowerShell.Admin; . "C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1"

Send an SMTP e-mail with PowerShell 2.0 or later
send-mailmessage -from $sendfrom -to $sendto -subject $subject -body $body -BodyAsHtml -smtpServer $smtpserver

Add an availability address space to access local public folder schedule+ FB
Add-AvailabilityAddressSpace -ForestName -AccessMethod PublicFolder

Query free/busy schedule+ public folder replica information
get-publicfolder -Identity "\NON_IPM_SUBTREE\SCHEDULE+ FREE BUSY"  -Recurse | ft Name,OriginatingServer,Replicas -wrap -auto

Query free/busy schedule+ public folder information on Exchange 2007/2010
get-publicfolder -Identity "\NON_IPM_SUBTREE\SCHEDULE+ FREE BUSY"  -Recurse | Get-PublicFolderItemStatistics | ft PublicFolderName,Subject -wrap -auto

Show the e-mail addresses for the specified user in list format
((Get-Mailbox user01).EmailAddresses)

Add a secondary e-mail address in Exchange 2010 to a mailbox user
Set-Mailbox user01 -EmailAddresses (((Get-Mailbox user01).EmailAddresses)+="")

Add a secondary e-mail address in Exchange 2010 to a MEU
Set-MailUser testuser01 -EmailAddresses (((Get-MaiLUser testuser01).EmailAddresses)+="") -whatif

Update the targetAddress attribute for an ADSI object
$user = [adsi]"LDAP://CN=testuser01,OU=Migrated,DC=domain,DC=local"; $user.put("targetAddress","")

List the client-side public folder permissions for all public folders
$pfperms = Get-PublicFolder -recurse | Get-PublicFolderClientPermission

Get the report from a Exchange 2010 new-moverequest operation
$MoveReport = (Get-MailboxStatistics -Identity user01 -IncludeMoveReport).MoveHistory

Add to the managedBy property of a distribution list
set-distributiongroup -id $group -managedby (((get-distributiongroup -id $group).managedby) += $user.identity.distinguishedName)

Find the current management roles that have distribution in the name
Get-ManagementRoleAssignment | where {$ -like '*recipient*'} -warningaction silentlycontinue | ft -wrap -auto

Find CAS array information for an Exchange 2010 installation

Find delegate access to a mailbox with Exchange 2010 SP1
adfind -b "DC=domain,DC=local" -f "(&(objectClass=User)(objectCategory=Person)(msExchDelegateListLink=*))" -h dc01.domain.local samaccountname msExchDelegateListLink

Find delegate access to a mailbox with Exchange 2010 SP1 through backlink
adfind -b "DC=domain,DC=local" -f "(&(objectClass=User)(objectCategory=Person)(MsExchDelegateListBL=*))" -h dc01.domain.local samaccountname MsExchDelegateListBL

Convert legacy global distribution groups to universal
Get-Group -ResultSize Unlimited -RecipientTypeDetails NonUniversalGroup -OrganizationalUnit "OU=Distribution Lists,OU=Resources,DC=domain,DC=local" | Where-Object {$_.GroupType -match 'global'} | Set-Group -Universal

Mail-enable legacy global DLs that have been converted to universal
Get-Group -ResultSize Unlimited -RecipientTypeDetails UniversalDistributionGroup -OrganizationalUnit "OU=Distribution Lists,OU=Resources,DC=domain,DC=local"  | enable-distributiongroup

Change group scope for non-universal groups to universal
Get-DistributionGroup -ResultSize Unlimited -RecipientTypeDetails MailNonUniversalGroup | Set-Group -Universal

Upgrade Exchange 2010 legacy groups
Get-DistributionGroup -ResultSize Unlimited | Set-DistributionGroup -ForceUpgrade

Extract all properties of one or more users and save to CSV
get-aduser -ldapfilter "(&(objectClass=User)(objectCategory=Person)(samaccountname=*.exchtest*))" -prop * | export-csv -path c:\temp\TestUsers.csv

Create a new display name with surname in UPPER and first in Title case
$newName = $user.LastName.toUpper() + ' ' + (Get-Culture).textinfo.totitlecase($user.FirstName)

Start a remote powershell session to an exchange 2010 namespace
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://cas01.domain.local/PowerShell/ -Authentication Kerberos;   Import-PSSession $Session

Start a remote powershell session to an exchange 2010 namespace using prefix
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://cas01.domain.local/PowerShell/ -Authentication Kerberos;   Import-PSSession $Session -prefix ResForest

Bitwise OR to whether whether grouptype is distribution or security
if (14 -bor 2147483648 -eq 14) {write-output "Distribution} else {write-output "Security"}

Find mailbox folder permissions in Exchange 2010
$mailbox = get-mailbox -id user01; get-mailboxfolderpermission -id ($mailbox.primarysmtpaddress.tostring() + ":\Calendar")

Find the Exchange 2010 autodiscover URL (then stored in SCP)
Get-ClientAccessServer | fl *autodisc*      

Find Exchange 2010 RBAC management roles
Get-ManagementRole -id 'Distribution Groups' | fl *

Find Exchange 2010 RBAC management role assignments
Get-ManagementRoleAssignment |where {$_.role -eq 'Distribution Groups'} | ft -wrap -auto

Select the value of a property as an array of strings rather noteproperty
$members = get-adgroup "CN=group,DC=domain,DC=local" -server $dc | get-adgroupmember -server $dc | %{write-output $_.SamAccountName.ToString()}

Convert a group from security to distribution
get-adgroup -id migtestdl3 | set-adgroup -GroupCategory 0

Find recipient info from multiple forests and group by primary SMTP domain
$recipients = get-recipient -domaincontroller dc01.domain.local -OrganizationalUnit "OU=People,DC=domain,DC=local" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited ; $recipients += get-recipient  -domaincontroller -OrganizationalUnit "OU=People,DC=target,DC=domain" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited ; $recipients | select @{N='EmailDomain';e={$_.primarysmtpAddress.tostring().split("@")[1]}} | group-object -prop EmailDomain | sort -prop Count | ft -wrap -auto

Find mailboxes from multiple forest and info on e-mail domain and islinked
$mailboxes = get-recipient -domaincontroller dc01.domain.local -OrganizationalUnit "OU=People,DC=domain,DC=local" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited  | get-mailbox -domaincontroller dc01.domain.local; $mailboxes += get-recipient  -domaincontroller dc01.taret.domain -OrganizationalUnit "OU=People,DC=target,DC=domain" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited | get-mailbox -domaincontroller; $mailboxes | select OriginatingServer,@{N='EmailDomain';e={$_.primarysmtpAddress.tostring().split("@")[1]}},IsLinked | group-object -prop OriginatingServer,EmailDomain,IsLinked | sort -prop Count | ft Count,Name -wrap -auto  

Find mailboxes with an ActiveSync device partnership
get-casmailbox -resultsize unlimited  | where {$_.HasActiveSyncDevicePartnership -eq 'true'}

Find the preferred domain controllers for the current Exchange 2010 session
Get-ADServerSettings | fl *

Set domain controller configuration for an exchange server
Set-ExchangeServer -StaticConfigDomainController dc01 StaticDomainControllers dc01,dc02 -StaticExcludedDomainControllers dc03 -StaticGlobalCatalogs gc01

Link an Exchange 2010 mailbox to a cross-forest security principal
get-mailbox user01 | set-mailbox -LinkedMasterAccount domain\user01 -linkeddomaincontroller dc01.domain.local

Get Exchange 2010 IMAP settings
Get-IMAPSettings -Server cas01

Disable policy and update the primary SMTP address of a 2010 mailbox 
get-mailbox -id "CN=user01,OU=People,DC=domain,DC=local" | set-mailbox -EmailAddressPolicyEnabled $false -PrimarySmtpAddress user01@domain.local

Find the server generating the Offline Address Book
Get-OfflineAddressBook | ft server,guid,AddressLists -wrap -auto (files stored in C:\Program Files\Microsoft\Exchange Server\V14\ExchangeOAB\)

Prepare an Exchange 2010 cross-forest move (create MEU and merge contact)
.\Prepare-MoveRequest.ps1 -Identity $username -RemoteForestCredential $cred -RemoteForestDomainController dc01.domain.local -LinkedMailUser -MailboxDeliveryDomain domain.local -TargetMailUserOU "OU=Resource Forest Accounts,DC=domain,DC=local" -UseLocalObject

Initiate an Exchange  2010 cross-forest move request
New-MoveRequest -Identity $username -RemoteLegacy -RemoteGlobalCatalog dc01.domain.local -TargetDatabase 'DB01' -RemoteCredential $cred -TargetDeliveryDomain 'domain.local' ?Verbose

Get an Exchange 2010 move request report
$moverequest = Get-MoveRequestStatistics -id user01 -IncludeReport; $

Get all the mailbox users in an OU and set a user property
get-mailbox -org "OU=Resource Forest Accounts,DC=domain,DC=local" | set-user -company 'Company01'

Check Exchange 2010 CAS RPC Client Access stats for online mode
$matches = select-string -pattern "2013-03" -simple -path "\\cas01\c$\Program Files\Microsoft\Exchange Server\V14\Logging\RPC Client Access\RCA_201303*"; $results = foreach ($match in $matches) {$line = $match.line;   write-output $line }; $results | out-file -file c:\temp\rpcusage.txt -encoding ascii; $rpc = import-csv -path c:\temp\rpcusage.txt -header date-time,session-id,seq-number,client-name,organization-info,client-software,client-software-version,client-mode,client-ip,server-ip,protocol,application-id,operation,rpc-status,processing-time,operation-specific,failures; $classic = $rpc | where {$_.'client-mode' -eq 'Classic' -and $_.'client-software' -eq 'outlook.exe'}; $classic | select client-name | group-object -prop client-name | ft -wrap -auto Count,Name

Find Exchange 2007/2010 mailbox statistics in MB (not with remote powershell)
get-mailbox -id user* | get-mailbox | get-mailboxstatistics | select DisplayName,ItemCount,@{n='SizeMB';e={$_.TotalItemSize.value.tomb()}} | ft -wrap -autosize

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

Read more!

Sunday, August 15, 2010

vSphere Storage vMotion traffic

This post provides information on storage vMotion in VMware vSphere 4 with ESXi 4.0 U2 hosts. While using storage vMotion to move data between unconnected storage, I conducted some simple testing to identify the networks and ports used for vMotion.

I’ve never seen an explanation of how storage vMotion works, and while it seems kind of obvious in retrospect, I thought some people might find this interesting.


  1. The scope of a storage vMotion operation is datacenter wide, not limited to clusters or which host can see which storage.
  2. In the testing conducted, storage vMotion relies upon the management network to transfer the disk data between the two ESXi hosts
  3. If this method was used to import a large number of VMs from foreign storage then the limitation would typically be the 1GB vmnic used for the management network.
  4. To allow the migration between datastores not visible by a single host, the VM would also be migrated between hosts.


Two hosts managed by single vCenter instance, vc01:
  1. esx01 part of the CLUS1 cluster
  2. esx02 not in a cluster
  3. esx01, connected only to the iSCSI SAN 1
  4. esx02, connected only to the iSCSI SAN 2

Management network on vmk0 using two GbE interfaces on both hosts. Vmk0 on the management network with load balancing based on the virtual port ID.


The test conducted was using storage vmotion to move a virtual machine through VirtualCenter on vc01 from a datastore visible only to esx02 to a datastore visible only to esx01.
  1. The source datastore was LUN02 (visible only to esx02) and the destination datastore was LUN01 (visible only to esx01).
  2. vMotion was used to automatically migrate the VM from esx02 to esx01 (as the VM had moved storage)

Traffic and network usage observed

  1. On esx02 unsupported console, vmk0 source (esx02), destination (esx01).
  2. Command: /bin/tcpdump-uw -I vmk0 -nn

  1. MbRx 190Mb/sec on software iSCSI NIC – Reading the disk information from iSCSI SAN 2 for the VM
  2. MbTx 136Mb/sec – Transmit the information across the management network to esx01.
  3. Command: resxtop --server esx02 (‘n’ for network information)

  1. MbRx 120Mb/sec – receiving the disk data from esx02 across the management network
  2. MbTx 200Mb/sec on software iSCSI NIC – writing the data to the SAN across the iSCSI network
  3. Command: resxtop --server esx01 (‘n’ for network information)

The following diagram shows the traffic flow of storage vMotion on an iSCSI network:

Read more!

Saturday, August 14, 2010

Resizing a VM's Windows system OS with Set-HardDisk

With vSphere PowerCLI Update 1 there is now an automated method of increasing the system disk of a virtual machine. This essentially performs the same thing as I’ve been doing manually for a while now - the disk is resized and mounted to a ‘helper vm’ and diskpart extends the disk, the helper VM is then shutdown and the risk removed, and when the resized VM starts up the OS prompts for a final reboot after detecting the disk change.

Note that both the target and helper VM must be powered off, and credentials must be passed or the helpervm argument is ignored. The guest credentials are used on the Windows helper VM to authenticate using the VMtools mechanism to invoke a command inside a VM.

$guetsusername = "domain\username"
$guestpass = Read-Host "Guest password (administrator of the server)?" -assecurestring
$hostusername = "root"
$hostpass = Read-Host "Host Password (VI SDK access to the ESX host)?" -assecurestring
$hostcredential = new-object System.Management.Automation.PSCredential($hostusername, $hostpass)
$guestcredential = new-object System.Management.Automation.PSCredential($guetsusername, $guestpass)
$sizeGB = 30
$sizeKB = $sizeGB *1024*1024
$harddisk = Get-HardDisk -vm vm01
Set-HardDisk -HardDisk $harddisk[0] -capacityKB $sizeKB -hostcredential $hostcredential -guestcredential $guestcredential -helpervm $vm

An error occurred when trying to use domain credentials to pass to the vCenter SDK – host credentials are required, not credentials to vCenter (which seems odd).

Set-HardDisk -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm helpervm
Set-HardDisk : 4/02/2010 1:25:04 PM    Set-HardDisk    919835D1-AD13-41DF-ABDE-D630E96FE722    While performing operation 'Connect to host service 'https://esx01/sdk' at port 902' the following error occured: 'Insufficient permissions in host operating system'
At line:1 char:13
+ Set-HardDisk  <<<< -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm helpervm

Another error occurred when trying to resize a VM, the script used failed.  Note that I tried this manually and it also failed (must have been something particular to that VM).  It was interesting to see that from this it looks like the cmdlet uses the invoke-vmscript to run a remote script through the VMtools interface that calls the diskpart commands.
Set-HardDisk : 4/02/2010 11:22:11 AM    Set-HardDisk    919835D1-AD13-41DF-ABDE-D630E96FE722    Execution of the  script in guest OS on VM 'helpervm' failed: '
Microsoft DiskPart version 5.2.3790.3959
Copyright (C) 1999-2001 Microsoft Corporation.
On computer: HELPERVM
Disk 1 is now the selected disk.
Volume 2 is the selected volume.
The volume you have selected may not be extended.
Please select another volume and try again.
At line:1 char:13
+ Set-HardDisk  <<<< -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm $vm

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

Read more!

Sunday, May 9, 2010

Keeping Citrix sessions alive with sendkeys

I use the following script as a way of keeping my Citrix session alive to thwart security guys and their over-aggressive timeouts.

Normally I don't like to use sendkeys, but this seemed like the perfect way to trick ica into thinking keys were being pressed...

PowerShell and VBScript versions below.

# Find the wfica.exe process and poke keystrokes at it, preventing a Citrix session from timing out
# Be careful what you have open and what keystrokes you poke

[System.Object[]]$processes = get-process | where {$_.ProcessName -eq "wfica32.exe"}
if ($processes.count -ge 1) { $process = $processes[0] }

if ($process -is [System.Diagnostics.Process])
  $processes | format-list -property *

  for (;;)
    [void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")

    start-sleep -seconds 1

    [void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
    start-sleep -seconds 240


Set objWshShell = CreateObject("Wscript.Shell")

strProcessName = "wfica32.exe"

intProcessID = 0
Call FindProcessID(strProcessName, intProcessID)

if (intProcessID > 0) Then
 wscript.echo "Found process ID: " & intProcessID

  WScript.Sleep 1000
  objWshShell.SendKeys "1"
  WScript.Sleep 240000

End If

Function FindProcessID(ByRef strProcessName, ByRef intProcessID)

 strQuery = "Select * from Win32_Process Where Name = '" & strProcessName & "'" ' WQL query string looking for the specified process

 Set objNameSpace = GetObject("winmgmts://./root/cimv2")    ' The cimv2 namespace of the local machine

 FindProcessID = vbFalse
 Set objProcessSet = objNameSpace.ExecQuery(strQuery)     ' Execute the query
 For Each objProcess in objProcessSet      ' For each process in the set, ordered by oldest to newest
  intProcessID = objProcess.ProcessID
  WScript.Echo "Found process, ID: " & intProcessID
  WScript.Echo objProcess.Name & ", " & intProcessID & ", " & objProcess.CreationDate & ", " & objProcess.CommandLine & ", " & objProcess.Priority & ", " & objProcess.WorkingSetSize & ", " & objProcess.PageFileUsage
  FindProcessID = vbTrue

 Set objNameSpace = Nothing : Set objProcessSet = Nothing : Set objProcess = Nothing
End Function

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

Read more!

Saturday, March 27, 2010

More useful command-lines

This is the third edition of useful command lines, adding another 95 commands that I've found useful. Note that many of the command-line calls may require Microsoft utilities (such as dsquery, wmic, dnscmd).

Most of the commands are for the windows-based command interpreter, with a few PowerShell and ESX service console commands creeping in. They range from diagnostics, troubleshooting and simply automating recurring tasks.

Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).

See the previous two posts for more command-line operations:

Given an IP and mask, return the subet the IP belongs to
for /f "tokens=1-8 delims=.- " %i in ('echo') do set /a Octet1="%i & %m" >nul & set /a Octet2="%j & %n" >nul & set /a Octet3="%k & %o" >nul & set /a Octet4="%l & %p" >nul & Echo %i.%j.%k.%l,!Octet1!.!Octet2!.!Octet3!.!Octet4!,%m.%n.%o.%p

Disable the internal speaker beep
sc config beep start= demand & net stop beep

List the Volume Shadow Copy Sets
vssadmin list shadows

List the volume Shadow Copy storage associations and sizes
vssadmin list shadowstorage

Create an FSRM storage report to check duplicate files
Storrept Reports Add /Report:DuplicateFiles /Task:FSRM-DuplicateFiles /Scope:"E:\Data" /Name:"Duplicate Files" /Format:CSV /

Create a scheduled task prior to creating a 2003 FSRM report 
schtasks /create /sc MONTHLY /D 1 /tn FSRM-DuplicateFiles /tr "storrept reports generate /scheduled /task:FSRM-DuplicateFiles" /st 19:00:00 /ru system

Find the number of mailboxes on the specified msExchHomeServerName
dsquery * -filter "(&(objectClass=User)(objectCategory=Person)(mailnickname=*)(msExchHomeServerName=*servername*))" -limit 0 | find /i /c "cn"

Join text copied from the command-line to a single line when pasting
Hold down the shift key when copying the text

Query the current control set, last known good and failed hives 
reg query HKLM\system\select

Make persistent changes to service control dependencies
sc \\%server% config snmp depend= EventLog/

Assign a drive letter to a recently created partition/volume
diskpart assign letter=e

Convert a group from type distribution to type security
dsmod group %groupDN% -secgrp Yes  

Query for global security or distribution groups
dsquery * -filter "(&(groupType:1.2.840.113556.1.4.803:=2))"

Query for global security groups
dsquery * -filter "(&(groupType:1.2.840.113556.1.4.803:=-2147483646))"

Given a list of group DNs, find if those groups are a member of other groups 
for /f "tokens=*" %i in (groups.txt) do @for /f "tokens=*" %m in ('"dsget group -memberof %i | find /i "cn" & if errorlevel 1 Echo Not a member of any groups"') do @echo %i,%m

Find the domain controller GUID of the specified DC 
dsquery * "CN=dcname,OU=Domain Controllers,DC=domainRoot" -scope base -attr objectguid

Find the domain GUID 
dsquery * "domainRoot" -scope base -attr objectGUID

Display the local WLBS Microsoft Network Load Balancing configuration
nlb display

Perform an LDAP ping against rootDSE to get the DC NETLOGON_SAM_LOGON_RESPONSE
adfind -rootDSE -f "(&(DnsDomain=domainFQDN)(Host=%computer%)(User=%computer%$)(DomainGuid=\30\FA\03\19\36\4F\47\1D\35\8F\C4\96\72\74\69\B3)(NtVer=\06\00\00\00))"  netLogon

Find the master browser for the subnet from NetBIOS browser
browstat getmaster \Device\NetBT_Tcpip_{3393FDD1-0D42-4DA4-8E53-36D9E00195F5} NETBIOS_DOMAIN_NAME

List the databases on an MSSQL 2005 server
sqlcmd -S %server% -d master -W -s "," -Q "SELECT NAME FROM sysdatabases Order By Name"

List the Service Control Manager security descriptor
sc sdshow SCMANAGER

Update the Service Control Manager SD on 2003 to allow non-admin access

Update the DACL for a service to allow a user to query and interrogate the svc
subinacl /service \\%server%\SysmonLog /grant=domain\user=QSI

Find DFS roots from Active Directory
dsquery * "CN=Dfs-Configuration,CN=System,domainRoot" -filter "(objectClass=fTDfs)"

List the DFS trust domain SPC cache
dfsutil /spcinfo

Find the SQL Server version
sqlcmd -S %server% -d master -W -s "," -Q "SELECT  SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')"

Find the SQL Server 2000 affinity mask 
sqlcmd -S %server% -d master -W -s "," -Q "select c.value from master..sysconfigures c, master..spt_values v, master..syscurconfigs r where v.type = 'C' and v.number = c.config and v.number >= 0 and v.number = r.config and ='affinity mask'"

Find the SQL Server 2005 affinity mask
sqlcmd -S %server% -d master -W -s "," -Q "SELECT Name, Value, Minimum, Maximum, Value_in_use, is_dynamic, is_advanced from SYS.Configurations Where Name = 'affinity mask'"

Find SQL Server 2005 configuration options
sqlcmd -S %server% -d master -W -s "," -Q "SELECT Name, Value, Minimum, Maximum, Value_in_use, is_dynamic, is_advanced from SYS.Configurations Order By Name"

Find SQL Server 2000 license information, Mode 0x0 per-seat, 0x2 per-proc
reg query "\\%server%\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\80\MSSQLLicenseInfo\MSSQL8.00

Find SQL Server 2000/2005 instances
reg query "\\%server%\hklm\software\microsoft\Microsoft SQL Server" /v InstalledInstances

Set environment variables for YYYYMMDD and YYYYMMDDHHMMSS
for /f "tokens=1-8 delims=/:. " %i in ('echo %date% %time%') do Set DateTime=%l%k%j&Set DateTimeLong=%l%k%j%m%n%o

Microsoft iSCSI, list sessions
iscsicli SessionList

Microsoft iSCSI, Report iSCSI and MPIO version information
iscsicli VersionInfo

Show disk usage by username (Windows Resource Kit)
diskuse c:\

Check whether external or forest trusts have SID filter qurantining enabled
nltest /domain_trusts /v

From a list of computers, run a command if the machine responds to a ping
for /f %i in (computers.txt) do @ping -n 1 %i >nul & if errorlevel 0 if not errorlevel 1 echo %i

Extract performance counters from a perfmon binary file and save as csv 
relog.exe -f csv Perfmon.blg -o perfmon.csv

Make a bootable CD using the specified boot sector file and source files
oscdimg /m /n /h -bc:\temp\bootsector.bin "c:\temp\source" install.iso

Find the Exchange storage groups known to AD
dsquery * "CN=Configuration,domainRoot" -filter "(&(objectClass=msExchStorageGroup))" -attr name msExchESEParamCircularLog msExchESEParamEventSource msExchESEParamLogFilePath msExchESEParamLogFileSize msExchESEParamSystemPath msExchESEParamZeroDatabaseDuringBackup msExchRecovery msExchESEParamEnableOnlineDefrag msExchESEParamEnableIndexChecking msExchESEParamBaseName msExchESEParamCommitDefault msExchESEParamDbExtensionSize msExchESEParamPageTempDBMin msExchESEParamPageFragment msExchESEParamCheckpointDepthMax

Check if an executable is large address aware (confirms support)
dumpbin /headers sqlservr.exe

Find all file/registry/thread/event details for a remote machine
psexec \\%server% -c handle.exe -a > c:\temp\handle.txt

Dump configuration with netsh that can be used to import
netsh interface ip dump > IPConfig.txt

Reapply settings saved with netsh export
netsh -f IPConfig.txt

List the SCSI devices for a group of machines
for /f %i in (computers.txt) do @for /f "tokens=1,2,*" %m in ('"devcon -m:\\%i listclass SCSIAdapter | find /i "VEN""') do @echo %i,%o

Adjust the priority of a process given its PID 
setprio /P %PID% /L 2

Find the paged and non-paged pool memory allocations

Create a local tag file for paged and non-paged pool memory allocations
poolmon /c

Add a trigger to an existing scheduled task
jt.exe /sac "\\%server%\c$\windows\Tasks\taskname.job" /ctj StartTime=15:10 StartDate=02/02/2010 type=DAILY typearguments=1

Find AdminSDHolder / SDPROP groups in the directory
dsquery * -filter "(&(objectClass=Group)(objectCategory=Group)(adminCount=1))"   

Query for all objects that are protected (that are members of the groups above)
dsquery * -filter "(adminCount=1)"

Count how many user accounts are protected by the SDPROP process
dsquery * -filter "(&(objectClass=User)(objectCategory=Person)(adminCount=1))" | find /i /c "CN="

Find disk and partition relationships
wmic path Win32_LogicalDiskToPartition

LDAP string to search for mail-enabled user and contact objects

Find SCPs (Service Connection Points) for objects other than print queues
dsquery * -filter "&((objectClass=ConnectionPoint)(!(objectClass=PrintQueue)))"  -limit 0

List VSS Shadowstorage associations
wmic /node:%server% path win32_shadowstorage

List VSS Max storage for disabled volumes
reg query HKLM\System\CurrentControlSet\Services\VSS\Volumes\Associations\{00b810fd-8ab6-11de-9d34-806e6f6e6963}\{00b810fd-8ab6-11de-9d34-806e6f6e6963}\MaxDiffSpace

Force a STOP error and generate a memory dump (Stop 0x2E) after enabling
Right Ctrl+ScrollLock+ScrollLock

Enable the option to generate a STOP error on demand
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\i8042prt\Parameters /v CrashOnCtrlScroll /t reg_dword /d 0x1

Logoff a remote terminal sessions session (after using query.exe)
logoff rdp-tcp#42 /v /server:%server%

List the DLL function exports of the specified DLL
dumpbin c:\temp\dllname.dll /exports

Terminate a disconnected terminal services session
rwinsta 0 /server:%server%

Find memory information from a list of machines
for /f %i in (computers.txt) do for /f "tokens=1-5" %m in ('"wmic /node:%i path Win32_PerfFormattedData_PerfOS_Memory get PoolNonpagedBytes,PoolPagedBytes,PoolPagedResidentBytes,FreeSystemPageTableEntries,AvailableMBytes | find /i /v "bytes""') do echo %i,%m,%n,%o,%p,%q

Set the percentage at which the paged pool working set is trimmed
reg add "\\%server%\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management" /v PoolUsageMaximum /t reg_dword /d 60

Calculate a replication summary for the domain
repadmin /replsum /bysrc /bydest /sort:delta

Check a 2008 R2 schema forest prep has run successfully (rvevision=5)
dsquery * "CN=ActiveDirectoryUpdate,CN=ForestUpdates,CN=Configuration,domainRoot" -attr * -scope base

Check a 2008 R2 schema domain prep has run successfully (revision=5)
dsquery * "CN=ActiveDirectoryUpdate,CN=DomainUpdates,CN=System,domainRoot" -attr * -scope base

Find the infrastructure role holder for the DNS domain application partition
dsquery * "CN=Infrastructure,DC=DomainDNSZones,domainRoot" -attr fSMORoleOwner   

Find the application partitions from the forest root configuration NC
dsquery * "CN=Partitions,CN=Configuration,domainRoot" -filter "(&(objectClass=crossRef)(msDS-SDReferenceDomain=*))" -attr ncName dnsRoot

Monitor the page faults of an application (hard and soft)
pfmon.exe c:\temp\application.exe

Monitor the page faults of a process (hard and soft)
psmon /p %PID%

Reset the SystemPages memory management for available PTE's to server 2003 def.
reg add "\\%server%\HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" /v SystemPages /t reg_dword /d 0x0x

Find Exchange mailbox limits for user accounts
csvde -f limits.csv -l samaccountname,cn,mDBStorageQuota,mDBOverQuotaLimit,mDBUseDefaults,mDBOverHardQuotaLimit,homeMDB -r "(&(objectClass=User)(objectCategory=Person)(mailnickname=*))"

Find computer accounts not server, XP or Vista
dsquery * domainroot -filter "(&(objectCategory=Computer)(objectClass=Computer)(&(!(operatingSystem=*prof*)(!(operatingSystem=*server*)(!(operatingSystem=*vista*))))))" -limit 0 -attr CN operatingSystem operatingSystemVersion

Find SPNs from the directory
dsquery * -filter "(servicePrincipalName=*)" -attr cn servicePrincipalName -limit 0

Query a list of groups and determine the group type (global/local/universal)
dsquery group -name *groupfilter* | dsget group -scope -secgrp -dn

Perform a NetBIOS name lookup
nblookup %NETBIOS_NAME%

Extract DNS scavenging events from the DNS eventlog
wmic /node:"%server%" path Win32_NTLogEvent WHERE "SourceName='DNS' AND LogFile='DNS Server' AND EventCode=2501"

Dump GPO information on priority and inherited links for an OU
cscript DumpSOMInfo.wsf "OUName" /ShowInheritedLinks

Copy a GPO 
cscript copygpo.wsf "Default Domain Policy" "Test Domain Policy" %SourceDC% %TargetDC%

Backup a number of GPOs from a control file input
for /f "tokens=*" %i in (gpos.txt) do cscript backupgpo.wsf "%i" c:\temp\gpo

Create a number of blank GPOs from a control file input         
for /f "tokens=*" %i in (c:\temp\gpo.txt) do cscript CreateGPO.wsf "%i" /

Add GPO permissions for a number of GPOs
for /f "tokens=*" %i in (c:\temp\gpo.txt) do cscript SetGPOPermissions.wsf "%i" domain\user /permission:fulledit

List the available features for a 2008 R2 online installation 
dism /online /get-features

Allow remote desktop connections on a 2008 R2 server (requires reboot)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t reg_dword /d 0x0

Allow remote desktop connections on a 2008 R2 server core  (requires reboot)
cscript C:\Windows\System32\Scregedit.wsf /ar 0

Set the boot timeout for a 2008 server
bcdedit /timeout 5

Modify startup and recovery settings prevent automatic restart on 2008 server 
reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\CrashControl /v "AutoReboot" /t reg_dword /d 0x0

Modify the performance options to adjust for best performance
reg add HKU\.default\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects /v VisualFXSetting /t reg_dword /d 0x2

Disable hibernation on 2008 server
powercfg -hibernate off

Change the default user profile to adjust performance options for best perf
reg load c:\users\Default\ntuser.dat & reg add HKLM\a\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects /v VisualFXSetting /t reg_dword /d 0x2 & reg unload hkml\a

Enable boot logging on 2008 server
bcdedit /set {default} bootlog yes  

Disable Windows Error Reporting on 2008 server
serverWerOptin /disable

Adjust windows server 2008 event log sizes to 128MB
wevtutil sl Security /ms:135266304

Install Windows Server 2008 R2 optional components (features and roles)
cmd /c start /w ocsetup RSAT-NIS;SNMP;WMISnmpProvider;WindowsServerBackup;WindowsServerBackupCommandlet;NetFx3;MicrosoftWindowsPowerShellISE /quiet /norestart /log:c:\temp\install.log

Check Microsoft iSCSI initiator MaxRequestHoldTime 
reg query "\\%server%\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0002\Parameters" /v MaxRequestHoldTime

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

Read more!

Thursday, January 14, 2010

PowerCLI: Copy-VMGuestFile

In VMware PowerCLI Update 1, a new cmdlet has been added to copy files to/from guest OS’s using the VMTools. Under normal circumstances this wouldn’t be all that useful, but if a machine is not accessible on the network – either a DMZ or a test-lab environment for example – there is now a method to easily copy files to and from the guest machines.

For example:

copy-vmguestfile -source c:\windows\system32\imageres.dll -destination c:\temp\ -vm vm01 -guesttolocal -hostuser root -hostpassword * -guestuser administrator -guestpassword *

Note that you need to specify the passwords, or not specify credentials at all for a prompt, or you can use a pscredential object.

Unfortunately wildcards are currently unsupported, but it would be easy to loop through local files within PowerShell to upload based on wildcards.

I ran this with the measure-command cmdlet to see how fast it was – about 0.5MB/sec– not too quick, but a lot better than nothing.

measure-command -expression {copy-vmguestfile -source c:\windows\system32\imageres.dll -destination c:\temp\ -vm vm01 -guesttolocal -hostuser root -hostpassword * -guestuser administrator -guestpassword *}

Seconds : 26
Milliseconds : 539
Ticks : 265390633
TotalDays : 0.000307165084490741
TotalHours : 0.00737196202777778
TotalMinutes : 0.442317721666667
TotalSeconds : 26.5390633
TotalMilliseconds : 26539.0633

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

Read more!

Sunday, November 29, 2009

vCenter file copy with virtual floppy disk

n an ESXi or vCenter environment, without network connectivity to a virtual machine from your administrative workstation it's quite hard to bi-directionally transfer files.

This post discusses a simple method I use for small quick file transfer from a secure virtual machine to my administrative workstation, using virtual floppy drives managed from the command-line.

This process uses vfd.exe, but presumably any virtual floppy software on your workstation could be used. The virtual machine also needs to have a floppy drive...

To bi-directionally transfer files from a non-network connected VM to my administrative workstation:

  1. Create a virtual floppy disk on my workstation

  2. Mount that floppy disk file as a virtual floppy drive on my workstation as A:

  3. Through VI client, connect the VM to the A: drive

  4. On the VM, copy files to/from A: drive and disconnect from the floppy

  5. On my workstation, copy files to/from the virtual A:

  6. Close the virtual floppy

Using vfd.exe:
  1. vfd install

  2. vfd open c:\temp\new.flp

  3. Use VI Client to connect to A:

  4. Copy files, then disconnect the VM virtual device

  5. copy a:\*.*

  6. vfd close

The obvious limitation of this is that the size is limited to 1.44MB. I tried with a 2.44MB floppy and the virtual machine didn't recognise this disk.

This doesn’t work with a virtual CD-ROM, as it’s mounted as read-only in the VM, so bi-directional copies aren’t available. You can still use a similar process for creating an ISO to copy files into a VM though. For this I use oscdimg.exe (Microsoft utility) to create my ISO from the command-line.

Read more!

Friday, October 30, 2009

VMware PowerCLI commands

The VMware PowerCLI PowerShell interface provided for managing vSphere systems is a fantastic tool that should be useful for all VMware admins.

I've gathered these commands while implementing and managing ESXi 4.0 clusters, use with caution on any production system.

This is an extension of a previous post:
VMware vSphere PowerCLI commands

Join a cluster by moving an ESX host from one location to the cluster
Move-Inventory -Item (Get-VMHost -Name esxHost) -Destination (Get-Cluster -Name clusterName)

Get the VMware.Vim.ClusterComputeResource MO from the PowerCLI cluster object
$clusterview = get-view $cluster.Id

Reconfigure a host for VMware HA (high availability)
$vmhost = get-vmhost -name esxHost; $hostMO = Get-View -ID $vmhost.ID; $hostMO.ReconfigureHostForDAS()

Find migration events for the last day
$events = Get-VIEvent -Start (Get-Date).AddDays(-1) | where {$_.fullFormattedMessage -match "Migrating.*"}

Find events other than CPU Alarms or user login/logout for the last day
$events = Get-VIEvent -Start (Get-Date).AddDays(-1) | where {$_.fullFormattedMessage -notmatch "Alarm.*CPU.*|User.*logged.*"}

Find events for degraded MPIO path redundancy 
$events = Get-VIEvent -Start (Get-Date).AddDays(-1) | where {$_.fullFormattedMessage -match "Path redundancy to storage.*degraded"}

Report the date, host and description for MPIO path redundancy errors
foreach ($event in $events) {write-output ($event.createdTime.ToString() + "," + $ + "," + $event.fullFormattedMessage)}

List a table of VI events with only the date and message
$events | format-table -wrap -autosize -property createdTime,fullFormattedMessage

List the physical networks adapters and the current link speed (ESX 4.0)
$hostSystem = get-view -ViewType HostSystem; $hostConfigManager = $hostSystem.get_ConfigManager(); $hostNetworkSystem = $hostConfigManager.get_NetworkSystem(); $netSystem = Get-View $hostNetworkSystem; $netSystem.NetworkConfig.pnic; foreach ($pnic in  $netSystem.NetworkConfig.pnic) {Write-Output ($pnic.Device + "," + $pnic.spec.linkspeed.SpeedMB)}

List the vSwitches and the uplinks currently attached
$hostSystem = get-view -ViewType HostSystem; $hostConfigManager = $hostSystem.get_ConfigManager(); $hostNetworkSystem = $hostConfigManager.get_NetworkSystem(); $netSystem = Get-View $hostNetworkSystem; foreach ($vswitch in  $netSystem.NetworkConfig.vSwitch) {Write-Output ($vSwitch.Name + "," + $vswitch.spec.policy.NicTeaming.NicOrder.ActiveNic)}

Remove snapshots from a group of machines
$VMs = Get-VM -Location (get-folder -name "vmFolder"); foreach ($vm in $vms) {remove-snapshot -snapshot (Get-Snapshot -vm $vm) -confirm:$false}

Take snapshots of a group of machines
$VMs = Get-VM -Location (get-folder -name "vmFolder"); foreach ($vm in $VMs) {New-Snapshot -Name "snapshot 01" -description "Snapshot description" -vm $vm -Quiesce:$false}

Find VM name, description and primary disk datastore
$VMs = get-vm; foreach ($vm in $VMs) {write-output ($vm.Name + ",""" + $vm.Description + """," + $vm.harddisks[0].FileName.Replace(" ", ",")) | out-file -append -filepath c:\temp\VM_Datastores.txt}

Bring a host out of maintenance most
Set-VMHost -VMHost esxHost -State Connected

Generate diagnostic support bundles for all hosts
get-log -vmhost (get-vmhost) -bundle -destinationpath c:\temp\bundles

Find the network adapter type for each VM
$vms = get-vm ; foreach ($vm in $vms) {write-host $vm.Name "-"  $vm.networkadapters[0].type}

Find physical NICs and whether they're set to autonegotiate or hardcoded
foreach ($pnic in $hostNetwork.pnic) {if($pnic.linkSpeed -eq $null) {$ls = "Auto"} else {$ls= $pnic.linkSpeed.speedMB.toString() + ":" + $pnic.linkSpeed.duplex} ;write-output ($pnic.Device + "," + $ls)}

Find host sytem build information
$hostSystems = get-view -ViewType HostSystem; foreach ($hostSystem in $hostSystems) {Write-Output ($hostSystem.Name + "," + $hostSystem.config.product.Fullname)}

Find VMs and whether the VMtools is configured to synchronising time 
$vmSet = Get-VM ; foreach ($vm in $vmSet) { $view = get-view $vm.ID ;$config = $view.config; $tools = $; Write-Output ($vm.Name + "," + $tools.SyncTimeWithHost) }

Revert to a snapshot
set-vm -vm vmName -snapshot (get-snapshot -vm vmName) -confirm:$false

Remove a virtual machine from inventory and delete from disk
remove-vm -DeleteFromDisk:$true -RunAsync:$true -vm vmName

Shutdown one or more Virtual Machine guests
shutdown-vmguest -vm $vms -confirm:$false

Start one or more Virtual Machine guests
start-vm -vm $vms -confirm:$false

Forcefully power off one or more Virtual Machines
stop-vm $vms -confirm:$false

Get a virtual switch from the specified ESX host
get-virtualswitch -name vSwitch1 -vmhost esxHost

Create a new port group on the specified vSwitch
New-VirtualPortGroup -Name "pgName" -VirtualSwitch $vs

Find ESX memory balloon averages for the last five days
get-stat -entity $hosts -start (Get-Date).AddDays(-5) -finish (Get-Date) -stat mem.vmmemctl.average

Export a list of VMs
$vms | select-object -prop Name | out-file -filepath c:\temp\vms.txt

Export a list of VM guest hostnames 
$vms = get-vm; foreach ($vm in $vms) { write-output $vm.guest.get_HostName()}

Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. 

Read more!

Tuesday, October 13, 2009

Service Control Manager Security for non-admins

Allowing non-administrators rights for service control sounds deceptively simple, but unfortunately it’s not. After Windows Server 2003 SP1, the default rights are very focused on administrator-only access for service control.

This post describes how to view and modify the security descriptor for the Service Control Manager (SCM) and individual services as required.

Show the descriptor for SCM:
sc sdshow SCMANAGER


In this case, the output shows that by default, Authenticated Users (AU) only have connect, but not enumerate (LC) for SCM.

If you want to allow a non-administrator to connect to the Service Control Manager and enumerate the services, you can modify the security descriptor by using something like the following command to add enumerate, read control and query lock status for Authenticated Users with SCM:
sc sdset SCMANAGER


This allows connecting to the SCM and enumerating services. However, if the DACL on the individual services only allows administrators access to the services, then they still won’t be accessible. You’ll need to run specific 'sc sdset' commands against particular services, or use subinacl to change all services with one command.

Note that the sc.exe version with XP does not support this syntax – use the sc.exe on 2003 server.

For individual services, you could then allow query and interrogate with the following command:

subinacl /service \\server\* /grant=domain\user=QSI

Note that to map the ACE flags to the meaning with regards to service control, I went through the following process:

  1. Find the access rights from the flag, eg CC = SDDL_CREATE_CHILD = ADS_RIGHT_DS_CREATE_CHILD (ACE Strings link below)
  2. Find the constant matching this value, eg. 0x1 (ADS_RIGHTS_ENUM Enumeration link below)
  3. Match this to the SCM access right for the hexadecimal value, eg. 0x1 = SC_MANAGER_CONNECT (Service Security and Access Rights link below)
Map between sdshow output, right, hex value and SC/service meaning:

"RC"  READ_CONTROL                       = 0x20000 READ_CONTROL

Access right Description for services and SCM:

SERVICE_QUERY_CONFIG (0x0001) Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration. 
SERVICE_CHANGE_CONFIG (0x0002) Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.  
SERVICE_QUERY_STATUS (0x0004) Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service. 
SERVICE_ENUMERATE_DEPENDENTS (0x0008) Required to call the EnumDependentServices function to enumerate all the services dependent on the service. 
SERVICE_START (0x0010) Required to call the StartService function to start the service. 
SERVICE_STOP (0x0020) Required to call the ControlService function to stop the service. 
SERVICE_PAUSE_CONTINUE (0x0040) Required to call the ControlService function to pause or continue the service. 
SERVICE_INTERROGATE (0x0080) Required to call the ControlService function to ask the service to report its status immediately. 
SERVICE_USER_DEFINED_CONTROL(0x0100) Required to call the ControlService function to specify a user-defined control code. 
SERVICE_ALL_ACCESS (0xF01FF) Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table. 
READ_CONTROL Required to call the QueryServiceObjectSecurity function to query the security descriptor of the service object. 

SC_MANAGER_CONNECT (0x0001) Required to connect to the service control manager. 
SC_MANAGER_CREATE_SERVICE (0x0002) Required to call the CreateService function to create a service object and add it to the database. 
SC_MANAGER_ENUMERATE_SERVICE (0x0004) Required to call the EnumServicesStatusEx function to list the services that are in the database. 
SC_MANAGER_LOCK (0x0008) Required to call the LockServiceDatabase function to acquire a lock on the database. 
SC_MANAGER_MODIFY_BOOT_CONFIG (0x0020) Required to call the NotifyBootConfigStatus function. 
SC_MANAGER_ALL_ACCESS (0xF003F) Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table. 

Directory service object access rights


ADS enum:

typedef enum  {
  ADS_RIGHT_DS_CREATE_CHILD          = 0x1,
  ADS_RIGHT_DS_DELETE_CHILD          = 0x2,
  ADS_RIGHT_ACTRL_DS_LIST            = 0x4,
  ADS_RIGHT_DS_SELF                  = 0x8,
  ADS_RIGHT_DS_READ_PROP             = 0x10,
  ADS_RIGHT_DS_WRITE_PROP            = 0x20,
  ADS_RIGHT_DS_DELETE_TREE           = 0x40,
  ADS_RIGHT_DS_LIST_OBJECT           = 0x80,


READ_CONTROL = 0x20000;


Applying Security Descriptors on the Device Object

Non-administrators cannot remotely access the Service Control Manager after you install Windows Server 2003 Service Pack 1;EN-US;907460

Securing a Remote WMI Connection

Configuring a Report Server for Remote Administration

Service Security and Access Rights

How to grant users rights to manage services in Windows 2000

How to troubleshoot WMI-related issues in Windows XP SP2

ACE Strings


Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. 

Read more!

Wednesday, September 30, 2009

VMware Command-Line Interface commands

The Windows command-line interface provided for managing ESX/ESXi systems is an invaluable tool for managing ESX infrastructure at the command-line. When using ESXi without a service console the CLI becomes even more useful.

I've gathered these commands while implementing and managing ESXi 4.0 clusters, use with caution on any production system.

ESXi 4.0 RCLI:

List the NTP servers used by the host --server esx01 --list

Add a Software iSCSI NIC named vmk2
esxcli --server=esx01 swiscsi nic add -n vmk2 -d vmhba33

List the Software iSCSI NICs
esxcli --server=esx01 swiscsi nic list -d vmhba33

List the software iSCSI status on a host --server esx01 --swiscsi --list

Enable software iSCSI on an ESX host --server esx01 --swiscsi --enable

List the adapters bound to software iSCSI
esxcli --server=esx01 swiscsi nic list -d vmhba33

List the VMKernel NICs --server esx01 --list

List the software iSCSI adapters --server esx01 --adapter --list

Set the iSCSI alias for the specified adapter --server esx01 --iscsiname --alias esx01 vmhba33

Bind a VMK software iSCSI NIC for MPIO PSA
esxcli --server=esx01 swiscsi nic add -n vmk2 -d vmhba33

Rescan a storage adapter bus --server esx01 vmhba33

Add a dynamic iSCSI discovery target --server esx01 --discovery --add --ip vmhba33

Add CHAP authentication to an iSCSI discovery target --server esx01 --authentication --level chapRequired --method CHAP --auth_username esxchap --auth_password chapacc3ss80 --ip vmhba33

Find the current ScratchConfig scratch location --server esx01 -g ScratchConfig.ConfiguredScratchLocation

Set the scratch location for ESXi --server esx01 -s "/vmfs/volumes/esxds01/Scratch/esx01" ScratchConfig.ConfiguredScratchLocation

Check if CIM OEM providers are enabled (such as Dell OM) --server esx01 -g UserVars.CIMOEMProvidersEnabled

Enable CIM OEM Providers (such as Dell OM) --server esx01 -s "1" UserVars.CIMOEMProvidersEnabled

Query the patches/updates/bulletins/VIBs installed on ESXi --server esx01 -q

Set the SNMP community for the ESXi host --server esx01 -c public

Enable the SNMP agent on an ESXi host --server esx01 -E

List the iSCSI node name --server esx01 --list --iscsiname --adapter vmhba36

List the preferred nativte multipathing (NMP) path for a device
 esxcli --server esx01 nmp fixed getpreferred -d naa.6090332880cfdc44fda634b1ca2457b8

Check whether round robin path selection is used for a device
esxcli --server esx01 nmp roundrobin getconfig -d naa.6090a02833cfdc7ffd4434b1ca5457b8 

List the disk NAA/UUIDs known to a host
esxcli --server esx01 nmp device list

List the MPIO path to device mapping --server esx01 -m

List the SCSI devices known to a host --server esx01 --list   

List the available datastores on a host --server esx01 --listds

List the contents of a datastore --server esx01 --dir [datastore]

Upload a local file to a datastore through vifs --server esx01 --put c:\temp\file.txt dir/file.txt?dsName=datastoreName

List virtual switches, port groups, uplinks and MTU -l --server esx01

Browse the datastores or local host through ssl
https://esx01/folder or https://esx01/host

Find the vmnic configuration, including driver, current speed --server esx01 -l 

Set a vNIC to auto-negotiate --server esx01 --vihost esx01 -a vmnic0

List the host-based files on an ESXi client --server esx01 --dir /host  

A few other useful VMware tips:

Recreate the rui.pfx file for VirtualCenter
openssl pkcs12 -export -in rui.crt -inkey rui.key -name rui -passout pass:testpassword -out rui.pfx

Forcefully power off a suspended VM
Delete the vmss file, and then power on the VM (state is lost)

ESXi 4.0, access unsupported ssh console through the dcui
Press Alt+F1, type unsupported, then the root password

Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. 

Read more!

All Posts

printQueue AD objects for 2003 ClusterVirtualCenter Physical to VirtualVirtual 2003 MSCS Cluster in ESX VI3
Finding duplicate DNS recordsCommand-line automation – Echo and macrosCommand-line automation – set
Command-line automation - errorlevels and ifCommand-line automation - find and findstrBuilding blocks of command-line automation - FOR
Useful PowerShell command-line operationsMSCS 2003 Cluster Virtual Server ComponentsServer-side process for simple file access
OpsMgr 2007 performance script - VMware datastores...Enumerating URLs in Internet ExplorerNTLM Trusts between 2003 and NT4
2003 Servers with Hibernation enabledReading Shortcuts with PowerShell and VBSModifying DLL Resources
Automatically mapping printersSimple string encryption with PowerShellUseful NTFS and security command-line operations
Useful Windows Printer command-line operationsUseful Windows MSCS Cluster command-line operation...Useful VMware ESX and VC command-line operations
Useful general command-line operationsUseful DNS, DHCP and WINS command-line operationsUseful Active Directory command-line operations
Useful command-linesCreating secedit templates with PowerShellFixing Permissions with NTFS intra-volume moves
Converting filetime with vbs and PowerShellDifference between bat and cmdReplica Domain for Authentication
Troubleshooting Windows PrintingRenaming a user account in ADOpsMgr 2007 Reports - Sorting, Filtering, Charting...
WMIC XSL CSV output formattingEnumerating File Server ResourcesWMIC Custom Alias and Format
AD site discoveryPassing Parameters between OpsMgr and SSRSAnalyzing Windows Kernel Dumps
Process list with command-line argumentsOpsMgr 2007 Customized Reporting - SQL QueriesPreventing accidental NTFS data moves
FSRM and NTFS Quotas in 2003 R2PowerShell Deleting NTFS Alternate Data StreamsNTFS links - reparse, symbolic, hard, junction
IE Warnings when files are executedPowerShell Low-level keyboard hookCross-forest authentication and GP processing
Deleting Invalid SMS 2003 Distribution PointsCross-forest authentication and site synchronizati...Determining AD attribute replication
AD Security vs Distribution GroupsTroubleshooting cross-forest trust secure channels...RIS cross-domain access
Large SMS Web Reports return Error 500Troubleshooting SMS 2003 MP and SLPRemotely determine physical memory
VMware SDK with PowershellSpinning Excel Pie ChartPoke-Info PowerShell script
Reading web content with PowerShellAutomated Cluster File Security and PurgingManaging printers at the command-line
File System Filters and minifiltersOpsMgr 2007 SSRS Reports using SQL 2005 XMLAccess Based Enumeration in 2003 and MSCS
Find VM snapshots in ESX/VCComparing MSCS/VMware/DFS File & PrintModifying Exchange mailbox permissions
Nested 'for /f' catch-allPowerShell FindFirstFileW bypassing MAX_PATHRunning PowerSell Scripts from ASP.Net
Binary <-> Hex String files with PowershellOpsMgr 2007 Current Performance InstancesImpersonating a user without passwords
Running a process in the secure winlogon desktopShadow an XP Terminal Services sessionFind where a user is logged on from
Active Directory _msdcs DNS zonesUnlocking XP/2003 without passwords2003 Cluster-enabled scheduled tasks
Purging aged files from the filesystemFinding customised ADM templates in ADDomain local security groups for cross-forest secu...
Account Management eventlog auditingVMware cluster/Virtual Center StatisticsRunning scheduled tasks as a non-administrator
Audit Windows 2003 print server usageActive Directory DiagnosticsViewing NTFS information with nfi and diskedit
Performance Tuning for 2003 File ServersChecking ESX/VC VMs for snapshotsShowing non-persistent devices in device manager
Implementing an MSCS 2003 server clusterFinding users on a subnetWMI filter for subnet filtered Group Policy
Testing DNS records for scavengingRefreshing Computer Account AD Group MembershipTesting Network Ports from Windows
Using Recovery Console with RISPAE Boot.ini Switch for DEP or 4GB+ memoryUsing 32-bit COM objects on x64 platforms
Active Directory Organizational Unit (OU) DesignTroubleshooting computer accounts in an Active Dir...260+ character MAX_PATH limitations in filenames
Create or modify a security template for NTFS perm...Find where a user is connecting from through WMISDDL syntax in secedit security templates

About Me

I’ve worked in IT for over 13 years, and I know just about enough to realise that I don’t know very much.