Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Ali Aces posted:

I'm not sure I follow (still kind of a neophyte at this), but if I'm getting you correctly:

the process{} block runs, and each iteration of it sends its output down the pipeline before the next iteration? It's already weird to me that the foreach loop doesn't seem to work like you'd expect it (I'd expect it to work in the begin{} block just as well, but it doesn't with pipeline input), but now I think I'm beginning to understand; so each call to write-output will actually send that output down the pipeline to the next, even before this function is finished? I didn't even realize that.

In any case, yeah for this particular function I wasn't really concerned about the process list going stale while it's running, but it's possible to end up with multiple of the same process, pipe the first instance into stop-process then get errors on the rest since it's pulling them from a cache. Not sure that's really a problem worth fixing to me, but it is good to understand.

So I guess what happens with pipeline input is:

Every function in the pipeline's begin{} block is run
The process{} block for the first command that's receiving pipeline input is run on the first object in the pipeline
Any output from that process is sent on down to any following commands to process{}
Then (or in parallel?) the first command process{}es the next element in its pipeline
Once all elements are finished the end{} blocks are called

Have I got that right?
Yeah, I think you have it exactly right. Best way is to see it in action:
code:
function Function1 {
[CmdletBinding()]
param(
    [Parameter(
        ValueFromPipeline=$true
    )]
    [int]
    $Val
)

    Begin {
        Write-Verbose 'Begin Function1'
    }

    Process {
        Write-Host "$_ - Function1"
        $_
    }

    End {
        Write-Verbose 'End Function1'
    }
}

function Function2 {
[CmdletBinding()]
param(
    [Parameter(
        ValueFromPipeline=$true
    )]
    [int]
    $Val
)

    Begin {
        Write-Verbose 'Begin Function2'
    }

    Process {
        Write-Host "$_ - Function2"
        $_
    }

    End {
        Write-Verbose 'End Function2'
    }
}

function Function3 {
[CmdletBinding()]
param(
    [Parameter(
        ValueFromPipeline=$true
    )]
    [int]
    $Val
)

    Begin {
        Write-Verbose 'Begin Function3'
    }

    Process {
        Write-Host "$_ - Function3"
        $_
    }

    End {
        Write-Verbose 'End Function3'
    }
}
Now, to call these functions:
code:
100,200,300 | Function1 -Verbose | Function2 -Verbose | Function3 -Verbose | ForEach-Object { Start-Sleep -Seconds 2 } | Out-Null
You'll see the output from the begin blocks right away, followed immediately by the first iteration of all 3 functions, then a 2 second delay, between the second and third iterations, then each end block right away.

To address your confusion about the "foreach loop": this is a quirk about using an array parameter that accepts pipeline input:
code:
[Parameter(ParameterSetName="ByName",Mandatory=$true,ValueFromPipeline=$true,Position=0)][String[]]$FileName
There are 2 ways to call this with multiple items (by parameter and by pipeline, respectively:
code:
Get-LockingProcess -FileName File1,File2,File3
File1,File2,File3 | Get-LockingProcess
When you call it by parameter, the Process{} block only gets called once, and the value of $FileName is an array.
When you call it by Pipeline, the Process{} block gets called once for each item, and the value of $FileName is a single item in each iteration.

When you use a foreach loop on an item that is not array, Powershell gracefully handles it as though it were an array that contained just that single item. It's very handy but can be confusing if you don't realize it.

It turns out this is perfect usage in a Process{} block though, because it allows you to neatly handle both ways of calling the function without writing any messy conditionals; your code inside the foreach loop will always be handling a single object.

And yes, each call to Write-Output will send the object down the pipeline, but I think it should finish the current instance of the process block before proceeding (it just won't run the End{} code yet).

Also, while Write-Output is the correct cmdlet to call, you can also just omit it:
code:
Write-Output $p
# same as
$p
One last thing I just realized about your function. You have 2 parameter sets, so the parameters are mutually exclusive. The process{} block uses 2 foreach loops against those. Since one of them will always be empty, the foreach loop for the empty parameter just won't run its body, so that turns out just fine.

But in case you wanted to know, you can explicitly test for which parameter set was called:
code:
$PSCmdlet.ParameterSetName
You can use that in an if or switch statement to determine which set you're using.

Adbot
ADBOT LOVES YOU

zzMisc
Jun 26, 2002

Briantist posted:

When you call it by parameter, the Process{} block only gets called once, and the value of $FileName is an array.
When you call it by Pipeline, the Process{} block gets called once for each item, and the value of $FileName is a single item in each iteration.

Ah I get it, that makes total sense. Thanks for the explanation!


Briantist posted:

But in case you wanted to know, you can explicitly test for which parameter set was called:
code:
$PSCmdlet.ParameterSetName

Thanks, I was actually thinking about just getting rid of the parameter sets since there's really no good reason why you couldn't throw both in there if you really wanted to. It'd deal with it just fine, you'd just get a big dump of all the processes together. I originally only put them in so it'd show two different syntaxes on the help page.

Sefal
Nov 8, 2011
Fun Shoe
This was a while back, but i finally finished the script, thx to your hints.

I wouldn't have thought to just automate the whole process. Once again thank you guys for steering me in the right direction.

code:
Function Check-ADUser
{
Param ($Username)

    #write-host "Username = " $Username    
    #$Username = ($Username.Split("\")[1])
    $ADRoot = [ADSI]''
    $ADSearch = New-Object System.DirectoryServices.DirectorySearcher($ADRoot) 
    $SAMAccountName = "$Username"
    $ADSearch.Filter = "(&(objectClass=user)(sAMAccountName=$SAMAccountName))"
    $Result = $ADSearch.FindAll()

    If($Result.Count -eq 0)
    {
        #Write-Host "No such user on the Server" | Out-Null
        $Status = "0"
    }
    Else
    {
        #Write-Host "User exist on the Server" | Out-Null
        $Status = "1"
    }
    
    $Results = New-Object Psobject
    $Results | Add-Member Noteproperty Status $Status
    Write-Output $Results    
}

	Write-Host -foregroundcolor Blue "This script will generate a user ID for a new AD user."

	Write-Host -Foreground Gray "---------------------------------------------------------------"

	$SurName = read-host "Last Name"
	$GivenName = read-host "First Name"
	
		
	
	if ($surname.length -lt 4) {$short=$surname.substring(0,2,$surname.length)} else {$short=$surname.substring(0,2)} 

	$samaccountname = $givenname.substring(0,1) + $Surname.substring(0,2) 
	
	
	$Status = (Check-ADUser -username $samAccountName).Status
 	If ($Status -eq 1) {
		write-host -foreground Green "User ID already in use.  Incremented Surname by 1"
		$samaccountname =  $givenname.substring(0,1) + $surname.substring(1,2) 
	} Else { }
	$Status = (Check-ADUser -username $samAccountName).Status
	If ($Status -eq 1) {
		write-host -foreground Green "User ID already in use.  Incremented Surname by 1 character after the previously used one"
		$samaccountname = $givenname.substring(0,1) + $surname.substring(2,2)  
	
 	} Else { }
	$Status = (Check-ADUser -username $samAccountName).Status
	If ($Status -eq 1) {
		write-host -foreground Green "User ID already in use.  Incremented Surname by 1 character after the previously used one"	
		$samaccountname = $givenname.substring(0,1) + $Surname.substring(3,2) 
	} Else { }
	$Status = (Check-ADUser -username $samAccountName).Status
 	If ($Status -eq 1) {
		Write-Host -Foreground Red "User account already exists. Goodbye."
		Exit
 	} Else { }	
	$DisplayName = $Givenname + " " + $Surname

	$userPrincipalName = $GivenName + $SurName 
	
	Write-Host -Foreground Gray "---------------------------------------------------------------"
        Write-Host -Foreground Green " "$DisplayName
        Write-Host -Foreground Gray "---------------------------------------------------------------"
	Write-Host " Logon ID:"$cfgTab$samAccountName;
	Write-Host " Display Name:"$cfgTab$DisplayName;	
	
    write-host -foregroundcolor Green "Processing complete"
	Write-Host -Foreground Gray "---------------------------------------------------------------"
        	
	Write-Host -foregroundcolor Blue "Logon ID is de beschikbare aanlognaam"

	Write-Host -Foreground Gray "---------------------------------------------------------------"

	write-host -foregroundcolor Green "Goodbye" 

snackcakes
May 7, 2005

A joint venture of Matsumura Fishworks and Tamaribuchi Heavy Manufacturing Concern

Ali Aces posted:

Hey I know this was from weeks ago now, but I've been meaning to post this and now it's cleaned up, so here:

code:
function Get-LockingProcess() {
<#
    .SYNOPSIS
    Find the process that is locking a particular file.
    .PARAMETER FileName
    The name(s) of the file(s) to check.
    .PARAMETER LockedFile
    The System.IO.FileInfo object(s) to check.
    .OUTPUTS
    Retuns a set of System.Diagnostics.Process objects with an additional "User" NoteProperty indicating what user has it locked.
    .EXAMPLE
    Get-LockingProcess *.dll | select Path,ProcessName,User
    .EXAMPLE
    Dir -Recurse -Path "$env:windir\system32" -Include powershell.exe | Get-LockingProcess | Stop-Process
    (Say goodnight!)
    .EXAMPLE
    Get-LockingProcess "$env:windir\system32\*.dll"
    (Grab a soda first)
#>
    [cmdletbinding()]
    param(
        [Parameter(ParameterSetName="ByName",Mandatory=$true,ValueFromPipeline=$true,Position=0)][String[]]$FileName,
        [Parameter(ParameterSetName="ByFile",Mandatory=$true,ValueFromPipeline=$true,Position=0)][System.IO.FileInfo[]]$LockedFile
    )
    begin{
        [System.Diagnostics.Process[]]$processes = Get-Process # Keep us from having to do this multiple times in cases of multiple files
    }

    process{
        foreach( $ThisName in $FileName ) {
            $TheseFiles = dir $ThisName -Force
            foreach ($ThisFile in $TheseFiles) {
                write-debug $ThisFile.FullName
                foreach ($p in $processes) {
                    if( ($p.Modules).FileName -Contains $ThisFile.FullName) {
                        $q = get-wmiobject -Class win32_process -Filter "handle LIKE '$($p.Id)%'"
                        $p | Add-Member -MemberType NoteProperty -Name 'User' -Value "$($q.GetOwner().Domain)\$($q.GetOwner().User)" -Force
                        Write-Output $p
                    }
                }
            }
        }
        foreach( $ThisFile in $LockedFile ) {
            foreach ($p in $processes) {
                if( ($p.Modules).FileName -Contains $ThisFile.FullName) {
                    $q = get-wmiobject -Class win32_process -Filter "handle LIKE '$($p.Id)%'"
                    $p | Add-Member -MemberType NoteProperty -Name 'User' -Value "$($q.GetOwner().Domain)\$($q.GetOwner().User)" -Force
                    Write-Output $p
                }
            }
        }
    }

    end{}
}

This is so friggin cool. poo poo, I need to get better at Powershell. I've been using it for really basic automation but this is great. Thanks a lot!

sorta edit: this thread's been around for a long while so I'm sure the info is in here somewhere but... besides just figuring out scripts as the need arises do you guys have any advice on a good book or some way to train myself as some sort of powershell ninja?

snackcakes fucked around with this message at 01:53 on May 2, 2015

ConfusedUs
Feb 24, 2004

Bees?
You want fucking bees?
Here you go!
ROLL INITIATIVE!!





The latest version of the Pwershell in a month of lunches book

zzMisc
Jun 26, 2002

ConfusedUs posted:

The latest version of the Pwershell in a month of lunches book

The author of which posted this fantastic 4-hour video, which is how I got started.

https://www.youtube.com/watch?v=-Ya1dQ1Igkc

snackcakes
May 7, 2005

A joint venture of Matsumura Fishworks and Tamaribuchi Heavy Manufacturing Concern

Ali Aces posted:

The author of which posted this fantastic 4-hour video, which is how I got started.

https://www.youtube.com/watch?v=-Ya1dQ1Igkc

Neat. I'll check that out!

ConfusedUs posted:

The latest version of the Pwershell in a month of lunches book

Been meaning to get this book. I was hoping to hold out to see if he'd come out with a new edition for 4 but...this version is probably good enough.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
That din jones video taught me as well. I recommend him to everyone.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Swink posted:

That din jones video taught me as well. I recommend him to everyone.
Don Jones is also (I think) the founder of Powershell.org, which has a bunch of free eBooks and a good forum.

I worked with them on creating a Powershell quiz on Smarterer, though until I just searched for it now, I hadn't realized it went live.

Hughmoris
Apr 21, 2007
Let's go to the abyss!
Is there an easy way to print a PDF file to a network printer, using powershell? I couldn't find an easy way to do it, so right now I'm having the script make the network printer be the default printer, then print to default printer.

Hughmoris fucked around with this message at 20:23 on May 5, 2015

Hughmoris
Apr 21, 2007
Let's go to the abyss!
Ignore.

12 rats tied together
Sep 7, 2006

Are you using powershell 4? Get-Printer and Out-Printer should probably do what you need. There's also the .Net System.Drawing.Printing namespace which you could use with some effort: https://msdn.microsoft.com/en-us/library/system.drawing.printing%28v=vs.110%29.aspx

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Reiz posted:

Are you using powershell 4? Get-Printer and Out-Printer should probably do what you need. There's also the .Net System.Drawing.Printing namespace which you could use with some effort: https://msdn.microsoft.com/en-us/library/system.drawing.printing%28v=vs.110%29.aspx

I'm using Powershell 2. It's a work computer running Windows 7, and I'm a bit leery about trying to update powershell to a newer version. I'll have to take a look at that Namespace link you provided. The method I'm using now works but its a bit...awkward.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Hughmoris posted:

I'm using Powershell 2. It's a work computer running Windows 7, and I'm a bit leery about trying to update powershell to a newer version. I'll have to take a look at that Namespace link you provided. The method I'm using now works but its a bit...awkward.
What are your concerns about upgrading powershell? If you already have .Net 4 then you just need to install WMF 4 to get it.

CLAM DOWN
Feb 13, 2007




There are no concerns with upgrading your version of Powershell. Please install 4.0! It's very good and much improved, the ISE is improved too!

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Briantist posted:

What are your concerns about upgrading powershell? If you already have .Net 4 then you just need to install WMF 4 to get it.

I'm not too familiar with PS, and with it being a work computer I'm not sure if an upgrade would have a negative impact on anything else installed.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Hughmoris posted:

I'm not too familiar with PS, and with it being a work computer I'm not sure if an upgrade would have a negative impact on anything else installed.
The only things I can possibly think of: Exchange 2010 and SharePoint 2010. When Powershell 3 came out, there were problems if you were doing administration for those products on a version higher than 2. I know this was fixed in an exchange update, and probably was in a sharepoint update too.

If you're not doing administration of those products directly from this machine, then seriously don't worry about it, do the upgrade.

If you are using those, just check for when the problems were fixed and see if the updates are installed.

To my knowledge, there was no such issue when v4 came out, everything worked.

Spazz
Nov 17, 2005

We're stuck on PS2.0 in production for our SharePoint farms. Validated environments :negative:

Sheep
Jul 24, 2003
Is there an easier way to forcibly remove the read only attribute on files recursively than this? ATTRIB won't cut it since some of the files are system/hidden and need to retain those flags (and ATTRIB skips them if they are set).

get-childitem . -recurse -force | where-object {$_.GetType().ToString() -eq "System.IO.FileInfo"} | Set-ItemProperty -name IsReadOnly -value $false -force

Sheep fucked around with this message at 18:34 on May 8, 2015

Zaepho
Oct 31, 2013

Sheep posted:

Is there an easier way to forcibly remove the read only attribute on files recursively than this? ATTRIB won't cut it since some of the files are system/hidden and need to retain those flags (and ATTRIB skips them if they are set).

get-childitem . -recurse -force | where-object {$_.GetType().ToString() -eq "System.IO.FileInfo"} | Set-ItemProperty -name IsReadOnly -value $false -force
You should be able to nuke the where-object by specifying the -file parameter on the get-childitem. May speed it up a bit. Aside from that, suspect this is as good at is gets without some crazy .net wizardry.

12 rats tied together
Sep 7, 2006

Instead of
code:
| where-object {$_.GetType().ToString() -eq "System.IO.FileInfo"} |
you can just do
code:
| ? { $_.IsReadOnly } |

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug
Yeah, be aware that calling the GetType method means you're using reflection, which is pretty slow. In general, if you find yourself reaching to GetType, chances are very good you're missing a better way of doing what you want to do.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
I'm trying to script out getting the total size of a few directories using:

code:
$startFolder = "C:\Users"

$colItems = (Get-ChildItem $startFolder -Recurse -Force | Measure-Object -property Length -sum)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB"
But, I'm having a couple of hangups. First, it's crapping out on any file > 248 characters in length. Second, specifically for Users, it's seeing all the weirdo special folders (AppData. Documents, Music, etc.) multiple times and wildly overcounting the size of the containing folders.

Any ideas?

zzMisc
Jun 26, 2002

Toshimo posted:

I'm trying to script out getting the total size of a few directories using:

code:
$startFolder = "C:\Users"

$colItems = (Get-ChildItem $startFolder -Recurse -Force | Measure-Object -property Length -sum)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB"
But, I'm having a couple of hangups. First, it's crapping out on any file > 248 characters in length. Second, specifically for Users, it's seeing all the weirdo special folders (AppData. Documents, Music, etc.) multiple times and wildly overcounting the size of the containing folders.

Any ideas?

Unfortunately, for whatever reason, one thing Powershell does not seem to deal with well at all are directory symlinks/junctions, which IMO is a pretty goddamn huge oversight for something running on an operating system that builds a recursive directory link directly into every user's profile.

However, you might be able to get it to work by adding -Attributes !ReparsePoint, or maybe -Attributes -notlike *ReparsePoint*, to your Get-ChildItem command.

See:
http://superuser.com/questions/528487/list-all-files-and-dirs-without-recursion-with-junctions
https://technet.microsoft.com/en-us/library/hh847897.aspx

22 Eargesplitten
Oct 10, 2010



Just starting out, learning the help commands. It seems like help and man are identical, while get-help gives all of the information and then scrolls all of the way to the bottom. Are there any other nuances?

CLAM DOWN
Feb 13, 2007




22 Eargesplitten posted:

Just starting out, learning the help commands. It seems like help and man are identical, while get-help gives all of the information and then scrolls all of the way to the bottom. Are there any other nuances?

You can see why that is by typing:

get-alias man

"man" is an alias for "help". The get-help cmdlet lets you pull up info on any given cmdlet. For example:

get-help select-object -full

Give it a try!

e: remember to try update-help first assuming you have an internet connection to download updated help files

myron cope
Apr 21, 2009

When I'm doing get-help stuff, I almost always do "help <whatever> -online" and view it in a browser

CLAM DOWN posted:

e: remember to try update-help first assuming you have an internet connection to download updated help files
I want to say you need to be in an administrator powershell session to do this too, I may be misremembering though

Zaepho
Oct 31, 2013

myron cope posted:

When I'm doing get-help stuff, I almost always do "help <whatever> -online" and view it in a browser

I want to say you need to be in an administrator powershell session to do this too, I may be misremembering though

Yes you need to be elevated for this since it updates the help globally.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin

22 Eargesplitten posted:

Just starting out, learning the help commands. It seems like help and man are identical, while get-help gives all of the information and then scrolls all of the way to the bottom. Are there any other nuances?

If you like the way that help/man don't scroll all the way down, you can make other commands do that by piping them to the command "more"

code:
Get-Command | more

Swink
Apr 18, 2006
Left Side <--- Many Whelps
I've done something stupid and run a start-dscconfiguration on my workstation. Now it processes the config every 30 mins which includes renaming my PC and a heap of other poo poo I do not want.

How do I tell the LCM to stop processing the DSC config?

Venusy
Feb 21, 2007
Does Stop-DSCConfiguration not work?

Swink
Apr 18, 2006
Left Side <--- Many Whelps
That seems to only stop an in-progress configuration.

I got around it by generating a new config with no configurations and applied it.

Hadlock
Nov 9, 2004

So I have been trying to refactor this python script in to Powershell. Basically it simulates (at a very basic level) people entering a bank, getting in lined, served by a teller and leaving.

The problem is that while Powershell offers a Get-Random function, you can specify a min and a max, but it doesn't have anywhere near Python's random.expovariate(lambd) function, which is described as,

python documentation posted:

"Exponential distribution. lambd is 1.0 divided by the desired mean. It should be nonzero. (The parameter would be called “lambda”, but that is a reserved word in Python.) Returned values range from 0 to positive infinity if lambd is positive, and from negative infinity to 0 if lambd is negative.". In another description, "expovariate() produces an exponential distribution useful for simulating arrival or interval time values for in homogeneous Poisson processes such as the rate of radioactive decay or requests coming into a web server.

The Pareto, or power law, distribution matches many observable phenomena and was popularized by Chris Anderon’s book, The Long Tail. The paretovariate() function is useful for simulating allocation of resources to individuals (wealth to people, demand for musicians, attention to blogs, etc.)."

On line 16 they use that function. Here's a youtube video describing it in great detail starting around 4:45

The TL;DR version is that you want random numbers, but 50% of the time you want the number to be between 0 and 1, 25% of the random numbers between 1 and 2, 12.5% of numbers to be between 2 and 3, 6.25% of numbers between 3 and 4, etc etc like this, but in a random order.



So I decided to write it. I'm having one of these moments,



Because it mostly works, but it's not quite right. Instead of 50/25/12.5/6.25 split I am getting 50/23/11/6. Which statistically is mostly within the margin of error on 1000 runs, but it's always low, never high. More importantly: I'm only getting these values when I set for a Median of 3, not of 1. I've having to multiply the result by three, effectively, to get the valid test data I want. Obviously this won't work very well/reliably if I have to massage the formula every time I modify my curve. If I set the median to 3 instead of 1, I come out with that split.

My functions were modeled after this (Pastebin of C# library). You don't need to dig any deeper than GetUint as it's effectively calling "Get-Random -Minimum -0.00 -Maximum 1"

Supposedly this is the model I should be following: log(1-$u)/(−λ)

code:
function GetUniform #GetUint
{
    Return Get-Random -Minimum -0.00 -Maximum 1
}



# Get exponential random sample with specified mean
function GetExponential_SpecMean{
param([double]$mean)

    if ($mean -le 0.0)
    {
                Write-Host "Mean must be positive. Received $mean."
                #throw new ArgumentOutOfRangeException(msg);
            }
    $a = GetExponential
    $R = $mean * $a
    Return $R
}


# Get exponential random sample with mean 1
function GetExponential
{
    $x = GetUniform
    Return -[math]::log10(1-$x) # -Math.Log( GetUniform() );
}

cls
$mean5 = 3
$rangeBottom = 3.0
$rangeTop = 4.0

$j = 0
$k = 0
$l = 0

    for($i=1; $i -le 1000; $i++){
        $a = GetExponential_SpecMean $mean5
   
        if($a -le 1.0){Write-Host $a;$j++}
        if($a -gt 1.0){Write-Host $a;$k++}
        if(($a -gt $rangeBottom) -and ($a -le $rangeTop)){#Write-Host $a;
        $l++}
    
        Write-Host "                      -> $i "
        }

Write-Host "One or less: $j"
Write-Host "Greather than one: $k"
Write-Host "Total in range between bottom $rangeBottom  and top $rangeTop : $l"

Hadlock fucked around with this message at 05:28 on May 26, 2015

Spazz
Nov 17, 2005

I wouldn't even know where to start with the math operations, but the nice thing about PowerShell is that if the cmdlet or assemblies don't exist, you can always write your own in C#. You might have better luck that way then looking for a cmdlet to do it for you.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Spazz posted:

I wouldn't even know where to start with the math operations, but the nice thing about PowerShell is that if the cmdlet or assemblies don't exist, you can always write your own in C#. You might have better luck that way then looking for a cmdlet to do it for you.
Yeah I was going to say, if the C# in your pastebin can already do what you want, just put it in a string and use Add-Type.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Swink posted:

That seems to only stop an in-progress configuration.

I got around it by generating a new config with no configurations and applied it.
Also see this:
http://stackoverflow.com/a/25526945/3905079

Hughmoris
Apr 21, 2007
Let's go to the abyss!
Kind of stumped here. I'm working with a CSV and following this technet tutorial.

My starting CSV is in this format:
code:
Facility ID, Pat Name,Pat Status,Account Number
FacilityA, Bob Bobby, Patient Active, 123456789
FacilityB, Henry Aaron, Patient Inactive, 23232323
Facility A, Babey Ruth, Patient Active, 565655656
I run this comman: Import-Csv c:\pwr_shell\testCSV.csv

and my output is this in this format:
code:
Facility ID    : A
Pat Name       : Bob Bobby
Pat Status     : Patient Active
Account Number : 123456789

Facility ID    : B
Pat Name       : Henry Aaron
Pat Status     : Patient Inactive
Account Number : 232323232

....
....
My problem is that I don't want that vertical format. I'd like it to display the header columns laterally instead of vertical, like the technet example:
code:
Name                       Department                 Title
----                       ----------                 -----
Pilar Ackerman             Research                   Manager
Jonathan Haas              Finance                    Finance Specialist
Ken Myer                   Finance                    Accountant
What am I missing here?

Hughmoris fucked around with this message at 03:17 on Jun 2, 2015

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Hughmoris posted:

Kind of stumped here. I'm working with a CSV and following this technet tutorial.

My starting CSV is in this format:
code:
Facility ID, Pat Name,Pat Status,Account Number
FacilityA, Bob Bobby, Patient Active, 123456789
FacilityB, Henry Aaron, Patient Inactive, 23232323
Facility A, Babey Ruth, Patient Active, 565655656
I run this comman: Import-Csv c:\pwr_shell\testCSV.csv

and my output is this in this format:
code:
Facility ID    : A
Pat Name       : Bob Bobby
Pat Status     : Patient Active
Account Number : 123456789

Facility ID    : B
Pat Name       : Henry Aaron
Pat Status     : Patient Inactive
Account Number : 232323232

....
....
My problem is that I don't want that vertical format. I'd like it to display the header columns laterally instead of vertical, like the technet example:
code:
Name                       Department                 Title
----                       ----------                 -----
Pilar Ackerman             Research                   Manager
Jonathan Haas              Finance                    Finance Specialist
Ken Myer                   Finance                    Accountant
What am I missing here?

The important thing to remember is that you have an object, with properties, and you can view and manipulate it as you see fit. The way it's displaying at the moment is in "List" format, probbaly because PowerShell determined it would fit better that way or be too crammed in a table.

But you can easily change that with Format-* cmdlets:

code:
$data = Import-Csv c:\pwr_shell\testCSV.csv

$data | Format-List
# $data | fl  <- Shorthand

$data | Format-Table
# $data | ft  <- Shorthand
If you want to display only certain columns, name them:
code:
$data | Format-Table 'Pat Name' , 'Pat Status'
Just remember that Format-* cmdlets should be the last item in your pipeline because they are for display only. You almost never want to assign the result of a Format-* cmdlet to a variable either.

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Briantist posted:

The important thing to remember is that you have an object, with properties, and you can view and manipulate it as you see fit. The way it's displaying at the moment is in "List" format, probbaly because PowerShell determined it would fit better that way or be too crammed in a table.

But you can easily change that with Format-* cmdlets:

code:
$data = Import-Csv c:\pwr_shell\testCSV.csv

$data | Format-List
# $data | fl  <- Shorthand

$data | Format-Table
# $data | ft  <- Shorthand
If you want to display only certain columns, name them:
code:
$data | Format-Table 'Pat Name' , 'Pat Status'
Just remember that Format-* cmdlets should be the last item in your pipeline because they are for display only. You almost never want to assign the result of a Format-* cmdlet to a variable either.

You're the man! The solved my problem. Trying to fumble my way through automating some tasks at work and its amazing how easy PowerShell makes it.

A quick google search showed me how simple it is to incorporate regex into the Where-Object command:
code:
$data = Import-Csv c:\pwr_shell\testCSV.csv | Where-Object {$_.'Facility ID' -match "^B"}
That will show me results for only the patients at Facility B, which I can then pipe into a new CSV.

Adbot
ADBOT LOVES YOU

high six
Feb 6, 2010
So I just finished Powershell in a Month of Lunches a few weeks ago and I think I have the basics of PS down pretty well. Where would someone move next book-wise? For background, I am a helpdesk monkey with some occasional admin stuff that I do.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply