PowerShell: Styling your Profile.

It may not be something we all wake up in the morning thinking about but to wake up and make your life just a bit easier is something we all think about. probably at more times through out the day.

The PowerShell profile that is going to be covered are both user based profiles.

One is the Shell Profile and the other is the ISE Profile.

both profiles are saved via the $profile defined path.

shell_Profile
Shell
ise_profile
ISE

These are essentially scripts with your preferences, functions, load frequently used modules, favorite variables, and etc.

I have been in some interesting situations where I automated report building into functions. Load specific modules that I use daily and some routine $variables to load that are always the same.

imagine how much time saving it would be to have your cup of coffee sitting and waiting on you in the car already made? that is the advantage the PowerShell Profile provides. A series of tasks, preparations that come automatic every time you click the sweet PowerShell emblem.

if you have network mapped user home folder, your profile can follow you to any and every server/machine you work on.

experiment and have fun with making your life easier.

any questions or comments let me know how you use your $profile !

How do you Compare?

Most people throw things at a problem and see what sticks.

Is this a true “solution” or a makeshift glue that can come unraveled at any given moment.

apples to oranges

I think that when we compare we should understand what is needed and not needed, and really understand our options.

Understand the basics

This is an example of a variable with text defined. we want to look for the word Fruit.

PS C:\> $Apple = "Red Fruit, Green Fruit, Yellow Fruit"

PS C:\> $Apple -match 'Fruit'
True

PS C:\> $Apple | where {$_ -match 'Fruit'}
Red Fruit, Green Fruit, Yellow Fruit

PS C:\> $Apple -like 'Fruit'
False

PS C:\> $Apple | where {$_ -like 'Fruit'}

 

So it looks like “Like” doesn’t like to be used in the way you cognitively expect.

PS C:\> $apple -like '*Fruit*'
True

PS C:\> $apple | where {$_ -like '*Fruit*'}
Red Fruit, Green Fruit, Yellow Fruit



Well there is a trick to it. The trick is it has rules that govern how it looks at the compared objects and if it care about what comes before or after the string you are looking for.

I like to use match. some instances like the Active Directory module that comes with RSAT doesn’t allow it with the -filter parameter. you can pipe and filter instead.

Take a look below:

PS C:\> get-aduser -filter {givenname -like *Xajuan*}

VS the pipeline equivalent below:

PS C:\> get-aduser -filter * | where {$_.givenname -match

Either way stay true to your comfort zone and be sure to explore outside it, because at the end of the day, you got to get the job done, and nothing compares like that is complete.

Enabling Remote Desktop remotely with PowerShell — from SID-500.COM

Consider the following scenario: There’s a switched on client computer in a branch office and you want to connect to that computer via remote desktop. Remote desktop is disabled by default on all Windows operating systems. There’s no user logged on this client computer and no one can help you to enable remote desktop. What […]

via Enabling Remote Desktop remotely with PowerShell — SID-500.COM

Functioning like an Adult. (In the Shell)

functioning like an adult

I would like to propose we should all function as adults at some point in life. maybe not 24 hours a day but enough to take care of ourselves.

PowerShell is an area that need you to be functioning to preserve your sanity and time, I will cover simple & advanced functions.

A function can save you a ton of typing and it could do quite a bit and be called using the infamous tab completion!

Simple Function Example:

Function Test-Google
{
Try{ $result=Test-Connection google.com
if ($result -ne $null){ write-host "Google is up and reachable" -ForegroundColor Green} 
}
Catch{write-host "Google Error Occured" -ForegroundColor Red}

}

 

Advanced Function Example:

Function Test-NetworkConnectivity
{
[cmdletbinding()]
param(
[parameter(ValueFromPipelineByPropertyName,ValueFromPipeline)][Object[]]$Website =@( "google.com","Bing.com")
)
Begin{}

Process{
FOREACH($SITE IN $Website)
{
Try{ $result=Test-Connection -ComputerName $site
if ($result -ne $null){ write-host "$site is up and reachable" -ForegroundColor Green} 
}
Catch{write-host "$site Error Occured" -ForegroundColor Red}
}
}
}

Take the time to explore tab completion.  this advanced function has way more capability and any questions?

 

 

Eventfully Troubleshooting Desktop Issues.

in the event you need to check your computer events to track down issues with your machine I must implore you to use “get-EventLog”

 

use this to your advantage to pinpoint issues.

 

in the image I used :

Get-EventLog -LogName system -Newest 1 -EntryType Error | Format-List

 

mainly to for word wrap and readability you can also automate this and dump to a report or email every so often.

 

 

Audit Objects in your Domain(s) Ready to Switch?

I find it important to figure out who and what is in your active directory OUs

get-aduser $TargetedUser

What about groups, and computers?

get-adobject $targetObject

this includes users, groups, and computers.

here is a switch that will report differently based on object class property that gets returned.

get-adobject -filter *| foreach-object{
Switch($_.Objectclass) {

User{ write-host "Found a User" -foregroundcolor red
      $_ | export-csv Users.csv -notypeinformation -append
     } #end User

Group{ write-host "Found a Group" -foregroundcolor blue
       $_ | export-csv Group.csv -notypeinformation -append
     } #end group

Computer{ write-host "Found a Computer" -foregroundcolor cyan
          $_ | export-csv Computers.csv -notypeinformation -append
     }#end Computer
}#end switch

}#end Foreach-object from pipeline

Add-Member if you want to effectively “object” all things and possess their property.

I thought I would clarify this as most articles don’t simplify this to easily wrap you head around.

Add-member is what I would use to add a new member to a group of properties on an object

  1. I create the object
  2.  Add a noteproperty that translate to text
  3. create a scriptmethod that can do things based on a scriptblock when called.
  4. create a scriptproperty that runs each time you call the $x object to display the results of it’s script block.
Here is the code:
$x=new-object psobject
$x| add-member -name ID – value “smithx” -membertype Noteproperty
$x| add-member -name ADlookup -value { get-aduser $x.name } -membertype scriptmethod
$x|add–member -name ADinfo -value {$x.adlookup()} -membertype Scriptproperty

if you want you can overwrite a member with the -force command.

Try & Catching Errors so you can relax Finally.

Sometimes you gotta Try…. okay enough pep talk.

using the Try Command will allow you to catch any terminating errors. unless you specify for some commands you will not catch the errors and may not want to actually.

example:

 Try{ get-childitem c:\incorrectlyspelledfolder\  -erroraction Stop -recurse -errorvariable ErrorCity}

#for every Try there must be a catch

Catch {write-host "Error: $($errorCity.gettype().fullname)"}

I wrote this to have the error show the  expression needed to catch specific errors you actually care about.

so you can to catches or specific instructions to go with specific errors. lie write this to one file and email the results on another catch instance.

Example:

  Try{ 
$folder="c:\windows"
get-childitem $folder -erroraction Stop -recurse -errorvariable ErrorCity -OutVariable Results 
}
 #for every Try there must be a catch #specific to error records now it will write the line.
catch [System.Management.Automation.ErrorRecord]{Write-host "Typo?"} #this catch will catch any other error like permission denied, etc. 
Catch {write-host "Error: $($errorCity.gettype().fullname)" -ForegroundColor Red} 


Finally{write-host "finished processing $folder " -ForegroundColor Green
        write-host "Sub Folders are :"
        $Results.fullname
        }
#finally is optional to do a set of command regardless of error on the object being processed.
Good Luck Trying & catching errors and finally understanding.

Stuffing Objects (Splatting or Hash)

so I seen this exchange command

Get-ReceiveConnector  is a neat cmd-let that allows for you to grab some quick information. but lets say the information was incorrect and you wanted to set up a newer connecter for Exchange.

you Stuff it in an Object:

$StuffedObject= Get-ReceiveConnector

Short Way : Clean

New-recieveConnecter  @stuffedObject -whatif

Long Way: (very messy)

$ReceiveConnectors | foreach {
New-ReceiveConnector -Name $_.Name -RemoteIPRanges $_.RemoteIPRanges -bindings $_.Bindings -Banner $_.Banner -ChunkingEnabled $_.ChunkingEnabled -DefaultDomain $_.DefaultDomain -DeliveryStatusNotificationEnabled $_.DeliveryStatusNotificationEnabled -EightBitMimeEnabled $_.EightBitMimeEnabled -DomainSecureEnabled $_.DomainSecureEnabled -LongAddressesEnabled $_.LongAddressesEnabled -OrarEnabled $_.OrarEnabled -Comment $_.Comment -Enabled $_.Enabled -ConnectionTimeout $_.ConnectionTimeout -ConnectionInactivityTimeout $_.ConnectionInactivityTimeout -MessageRateLimit $_.MessageRateLimit -MaxInboundConnection $_.MaxInboundConnection -MaxInboundConnectionPerSource $_.MaxInboundConnectionPerSource -MaxInboundConnectionPercentagePerSource $_.MaxInboundConnectionPercentagePerSource -MaxHeaderSize $_.MaxHeaderSize -MaxHopCount $_.MaxHopCount -MaxLocalHopCount $_.MaxLocalHopCount -MaxLogonFailures $_.MaxLogonFailures -MaxMessageSize $_.MaxMessageSize -MaxProtocolErrors $_.MaxProtocolErrors -MaxRecipientsPerMessage $_.MaxRecipientsPerMessage -PermissionGroups $_.PermissionGroups -PipeliningEnabled $_.PipeLiningEnabled -ProtocolLoggingLevel $_.ProtocolLoggingLevel -RequireEHLODomain $_.RequireEHLODomain -RequireTLS $_.RequireTLS -EnableAuthGSSAPI $_.EnableAuthGSSAPI -ExtendedProtectionPolicy $_.ExtendedProtectionPolicy -ExtendedProtectionTlsTerminatedAtProxy $_.ExtendedProtectionTlsTerminatedAtProxy -SizeEnabled $_.SizeEnabled -TarpitInterval $_.TarpitInterval -Server $NewServer -WhatIf

 

 

Robocopy is PowerShell’s Robust-tool.

See the source image

So lets create a scenario,  and say that they were having difficulty using Robocopy commands within or with PowerShell. Here’s a demonstration of how to use PowerShell to be able to deliver seamless and accurate commands that will ensure that you will have your data copied and have your PowerShell script.

The best part of PowerShell is the ability to manipulate objects of different types in the same way regardless of data type.

let’s start with planning out the end product and work towards constructing our objects.

 

Import your file with source and destination or you can wing it into a function. For demonstration purposes we will cover both.

 

Example 1: Scripted with external file input 

$data=import-csv data.csv

$count=0

$total=$data.count

foreach($item in $data)

{

$count+=1 #some people use $count++

$source= $item.source

$destination=$item.Destination

Write-Progress -Activity “Copying $source to $destination” -PercentComplete ($count/$total*100)

Robocopy $source $destination /mir /mt:8 /r:1 /w:1

} #end foreach statement in script

 

This one s a little tricky due to the possibility of quotation exceptions;  Folders with spaces that require quotes.

 Example 2: Interactive PowerShell session

set-location c:\rootoftargetfolders

get-childitem  |foreach-object {
$source= $_.fullname
$destination=”d:\destinationfolder\$($_.basename)”
Robocopy “$source” “$destination” /mir /mt:8 /r:1 /w:1
} #end foreach-object

 

Example 3: Function best saved in $profile (PowerShell Profile) 

function RoboCopy-Item ($Source,$destination)

{

Robocopy $Source” “$Destination /mir /mt:8 /r:1 /w:1

} #end function

#now to try it

RoboCopy-item  -Source c:\files -destination D:\usb_documents

 

Conclusion:

I know sometimes dealing with syntax can be a headache but when you take the time to experiment with the shell it is a good path to accumulate lessons learned.

RoboCopy and PowerShell can play nice, of course adding in some try/catch to control your logging output to a text, html or csv or installing a module that can output logs directly to Microsoft Excel or take the old-school approach and use the /log file switch for RoboCopy.