PowerShell

Powershell – parameters & credentials

Just a quick blog; am working on a script that requires credentials to run against a REST API, and a developer wanted to convert that script to use command-line parameters. I built this script (and quick test) to show that the command-line parameters create the same object as the Get-Credential object.

#define command line parameters
param (
    [string] $User,
    [string] $PWordClearText
)
#assign paramter values to appropriate objects, including creating a credential

$PWord = ConvertTo-SecureString -String $PWordClearText -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord

#Get credential from prompt
$Credential2 = Get-Credential

#compare the two credentials to validate
Compare-Object $Credential2.GetNetworkCredential().Password $Credential.GetNetworkCredential().Password -IncludeEqual

Nothing exciting or in-depth, but this is the foundation for automating a script I wrote to run under specified credentials.

#NeverStopLearning 10 Minutes of Code: PS Array .Add

One of the scripts I’ve been working through in my spare time is a script to identify what servers I can’t reliably use Powershell remotely on. We manage a large domain of legacy servers, and it’s been sliced into smaller segments that have some complex routing; it’s a bit of a nightmare, but I figured I could probe each computer and run some basic PS script to see if it responds.

However, we have a LOT of servers, and some of them fail even the basic ping test. Why waste resources on testing PS commands when I can’t even reach those? My solution? Run a ping test first, and build two arrays: one that contains pingable servers, and one that does not.

 Foreach ($computer in $computers)
{
#ping test first; if it fails, add it to a new array $aNoPing with the .Add method
if(-not (test-connection -ComputerName $computer.Name -COUNT 1 -Quiet))
{
    [void]$aNoPing.Add($computer)
 }
else #it pinged, add it to a new array $aComputers for the rest of the test
    {
        [void]$aComputers.Add($computer)
    }
}                       
#generate some output; these boxes need to be looked at.
Write-Output “”
Write-Output “The following servers cannot be reached by ping.”
Write-Output “————————————————“
$aNoPing

#NeverStopLearning 10 Minutes of Code : PS Select-Object

For a database person, this particular cmdlet has a lot of potential. I started monkeying around with Get-ComputerInfo, and was overwhelmed with the amount of properties that are returned by this command. I only wanted to select a few, and so I started looking at Select-Object. By piping the output of one command to this Select-Object, I could return only the properties I’m interested in (and it’s in a tabular format).

Get-ComputerInfo | Select-Object CsCaption, CsModel

I’m trying to develop a script that will connect to every server in a given list, and validate if I can execute PowerShell remotely on it. I’m getting there. Get-ComputerInfo is too heavy (it reads a lot more information than I need), but being able to pipe the output of a command will help me immensely.

More to come.

#NeverStopLearning: PS Comments, Variables, IF, Remove-Item, Write to a file

Bunch of stuff today in 10 minutes; again, this is my collection of notes, so the actual blog post my be less glamorous than the excitement I felt. PowerShell appears to be a very powerful scripting language, and the more I use it, the more I like it. However, like most coding languages, the syntax varies. For example, I finally had to give up and Google how to write a comment.

#This is a single line comment in PowerShell
<#This is a 
multi-line comment in Powershell #>

Comments are useful as scripts get longer. For my sample script, I wanted to try a few things today:
1. write something to a text file
2. Do some conditional logic
3. delete a file, and
4. declare and use a variable

Script below, and explanations later:

#Define a variable
$File = "C:\list.txt"

#the following code will drop the file if it exists
IF (Test-Path $File) {
Remove-Item $File }

Get-ChildItem -Path C:\ | Set-Content -path $File

Code is straightforward, but one explanation that may be tough for experienced programmers; there’s no type declaration for the variable. Everything in PowerShell is an object, which is why the variable is simple to declare and re-use. Furthermore, when piping the contents of Get-ChildItem to a file, it knows to write them as text. This may confuse me later, but for now, I grok it.

#NeverStopLearning: 10 Minutes of Code – PS Get-ChildItem

In my last post, I started working on a very simple script to explore files in a directory using PowerShell: Get-ChildItem allows me to find the files and folders in the user directory, but what if I wanted to start with a different directory? That’s where the -Path switch comes in.

Get-ChildItem -Path C:\

gives em a listing of all of the files and folders at the root of my C drive. Lots more to come; this is just the beginning of my journey.

#NeverStopLearning: 10 Minutes of code

Today, I spent 10 minutes working on PowerShell. I’ve never really spent much time in PowerShell before. I’ve had a few classes a few years ago, but like most things, if you don’t use it, you lose it.  I was going to do a Pluralsight course, but frankly, I haven’t been great about following up on these sorts of things, so I figured I’d start with the completely free (no trial expiration) knowledge at the MS Docs site

I knew most of this stuff, but the point of this exercise is to force myself to start using again.  I spent a few minutes running the ISE, using Get-Help (and updating the help files), and then thought I’d try a quick script.  Like most coders, I stole this from the web:

Get-ChildItem | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-180)}

This simple script helped me find the files and folders in my user directory (the current context) that were modified within the last 180 days.  To limit the results to files only, I added an additional clause to the filter:

Get-ChildItem | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-180) -and ! $_.PsIsContainer }

I think I can do this.  More to come.