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
anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

Roargasm posted:

yeah my only real problem right now is this logic:

$nodeVMs | % { if ($noLiveMigrateVM -match "$_.Name") {
$canPatchHypervisor = 0
break
}

I can't find a comparison operator that will return true. Tried $noLiveMigrateVM -containts $_.Name, etc. Always seems to return false
You can use debugging checkpoints in the ISE to determine what $_.Name is before it hits that if statement, or you can put Write-Host $_.Name; before the if statement to get it to spit out into the console, because it sounds like it's not what you think it's supposed to be.

Adbot
ADBOT LOVES YOU

Roargasm
Oct 21, 2010

Hate to sound sleazy
But tease me
I don't want it if it's that easy
That string was right, it was just the array comparison loving me I think. Ran out of time I ended up doing a really lovely nested loop and used remove duplicates in excel :(

$nodeVMs | % {
$vmName = $_.Name
$noLiveMigrateVM | % {
if ("$vmName" -match $_) {
echo "$hostname"
}

The Fool
Oct 16, 2003


I'm wrong and dumb.

The Fool fucked around with this message at 00:12 on Apr 29, 2017

thebigcow
Jan 3, 2001

Bully!

anthonypants posted:

Is your script calling another script?

No.

Opening the PowerShell console takes almost exactly five seconds, the ISE loads near immediately. This is a new behavior since the last Windows Update that I haven't noticed until today because I guess I've been using the ISE for everything. I made a blank profile.ps1 to see if that was it and no dice. There is no profile.ps1 in $PSHOME. The x86 version loads almost immediately. :iiam:

I need to catch up on month end stuff before I can look into this again.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy
There are four profiles you can look at. In an affected PowerShell window, check:

code:
$profile.AllUsersAllHosts
$profile.AllUsersCurrentHost
$profile.CurrentUserAllHosts
$profile.CurrentUserCurrentHost
Maybe there's something in one of those.

Also try opening powershell without a profile:

code:
powershell.exe -NoProfile

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

thebigcow posted:

I have a few scripts that I run from the right click menu because they have to be used by non-technical people if I'm out. Current execution policy is RemoteSigned. A recent Windows update installed PowerShell 5.1 and now I get a prompt after running these scripts:
Some PS update changed the default action on .ps1 files to programmatically (this is what causes the prompt) set the process execution policy to Bypass if it's not AllSigned. You can either sign your script and set the default policy to AllSigned, or change the action via the registry.

The Fool
Oct 16, 2003


Just going to leave this here as a monument to my stupidity. It took me entirely too long to figure this out.



edit: vvv- The actual code does stuff, those are just watch expressions in the VS Code debugger.

The Fool fucked around with this message at 23:29 on May 1, 2017

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

The Fool posted:

Just going to leave this here as a monument to my stupidity. It took me entirely too long to figure this out.

:negative:
code:
if (Get-ConnectionStatus) { return $(Get-ConnectionStatus) }

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

anthonypants posted:

:negative:
code:
if (Get-ConnectionStatus) { return $(Get-ConnectionStatus) }
code:
if ($((Get-ConnectionStatus) -eq $true) -and -not (Get-ConnectionStatus) -eq $false) { return $(Get-ConnectionStatus) -eq $true -and -not (Get-ConnectionStatus) -eq $false } else { return -not (Get-ConnectionStatus) -eq $true -and -not $(Get-ConnectionStatus) -ne $false }
code:
if ("$(Get-ConnectionStatus)" -eq [bool]::TrueString -and -not "$(Get-ConnectionStatus)" -eq [bool]::FalseString) { return [bool]::Parse("$("$(Get-ConnectionStatus)" -eq [bool]::TrueString -and -not "$(Get-ConnectionStatus)" -eq [bool]::FalseString)") } else { return [bool]::Parse("$(-not "$(Get-ConnectionStatus)" -eq [bool]::TrueString -and -not "$(Get-ConnectionStatus)" -ne [bool]::FalseString)") }

Briantist fucked around with this message at 17:47 on May 2, 2017

kaynorr
Dec 31, 2003

For those interesting in such things, the Powershell.org channel on YouTube just uploaded sessions from last week's PowerShell + DevOps Global Summit. Content from previous years has been very good, so I figured I would pass this along.

Bunni-kat
May 25, 2010

Service Desk B-b-bunny...
How can-ca-caaaaan I
help-p-p-p you?
Okay, I need a sounding board for this.

We're changing the name of a building, and they want it updated on everyone's AD profile. How's this look?

code:
get-aduser -Filter * | set-aduser -physicalDeliveryOfficeName "Main Building*" -replace "Main Building", "New Building"
The goal is to be able to run this against the whole AD group and change just the building name in the office field, and leave the office number intact, and not change anything for the users in other buildings. How's it look?

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

Avenging_Mikon posted:

Okay, I need a sounding board for this.

We're changing the name of a building, and they want it updated on everyone's AD profile. How's this look?

code:
get-aduser -Filter * | set-aduser -physicalDeliveryOfficeName "Main Building*" -replace "Main Building", "New Building"
The goal is to be able to run this against the whole AD group and change just the building name in the office field, and leave the office number intact, and not change anything for the users in other buildings. How's it look?
I don't believe Set-ADUser has a -physicalDeliveryOfficeName parameter.

Looks like it's just -Office.
code:
$users = Get-ADUser -Filter * -Properties Office | Where-Object {$_.Office -like "Main Building*"}
foreach ($u in $users) {
  Set-ADUser $u -Office ($u.Office -replace "Main Building","New Building") -WhatIf
}

anthonypants fucked around with this message at 19:43 on May 19, 2017

Bunni-kat
May 25, 2010

Service Desk B-b-bunny...
How can-ca-caaaaan I
help-p-p-p you?
That's what I get for doubting myself. I had -office in my first draft but changed it because of a random article I found. Thanks.

Inspector_666
Oct 7, 2003

benny with the good hair
There's Office and StreetAddress, but yeah, no PhysicalDeliveryOfficeName.

Just do a Get-Aduser your.name -properties * to double check.

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
To be fair, if you're in the Attribute Editor, and maybe if you're looking at ADSIEdit or at LDAP, there is an attribute named pysicalDeliveryOfficeName. But it's also the Office field under the General tab of an ADUC window, and that's just the way it is in Set-ADUser.

Bunni-kat
May 25, 2010

Service Desk B-b-bunny...
How can-ca-caaaaan I
help-p-p-p you?
Thanks anthonypants, your revision worked perfectly.


Inspector_666 posted:

There's Office and StreetAddress, but yeah, no PhysicalDeliveryOfficeName.

Just do a Get-Aduser your.name -properties * to double check.

I saw a script sample with a screenshot of attribute editor, and when I checked, the office line in properties was the same as the pdon line in attribute editor, so I made an assumption, which was wrong! But you guys continue to be super helpful.

Collateral Damage
Jun 13, 2009

Dumb question time: Some times when concatenating variables I see people use $($variable) and some times just $variable. What's the difference?

nielsm
Jun 1, 2009



Collateral Damage posted:

Dumb question time: Some times when concatenating variables I see people use $($variable) and some times just $variable. What's the difference?

The former lets you concatenate with variable-name-valid characters right of the name.

E.g.: "Free space: $(variable)MB"
If you wrote "$variableMB" it would look for a variable actually named variableMB instead.

Actually, what it really does is let you put entire expressions inside an interpolated string, so you can do things like:
"Free space: $($freeSpace/$totalSpace*100)%"

Zaepho
Oct 31, 2013

Collateral Damage posted:

Dumb question time: Some times when concatenating variables I see people use $($variable) and some times just $variable. What's the difference?

I feel like $($var) is more explicit. Additionally, it is more consistent when you may be accessing an object's properties a la $($Var.Prop) which otherwise would come out more like $($Var).Prop generally not what you're intending.

In my scripting I use $() in every single case of a variable inside a quoted string much like I refuse to use aliases like GCI instead of get-childItem or cast a variable I expect to be an array and will treat as an array as an array. I want to be clear and specific in my code so there is a little room for misinterpretation and be as explicit as reasonably possible to ensure things work as expected in as many use cases as possible.

Collateral Damage
Jun 13, 2009

I figured it was something like that, but some times I see people do it when there's whitespace around as well like "There are $($foo) items available", but I guess there's some value in being consistent.

nielsm
Jun 1, 2009



I certainly think the parentheses makes it easier to pick out when reading code without syntax highlighting, too.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Collateral Damage posted:

Dumb question time: Some times when concatenating variables I see people use $($variable) and some times just $variable. What's the difference?

It's to use an entire sub-expression. Inside those parentheses, you can have an entire script; the result of it will be converted/coerced to a string and put inside.

If you're using a property of an object, or anything other than the variable name then you would have to use this syntax; I wouldn't recommend using it for other purposes.

If you have to disambiguate between the variable name and the rest of the string, or if you have a variable name with odd characters, then you can use the curly brace syntax instead:

code:
$n = 5
"this is the $nth thing"
That won't work, because PowerShell can't tell that you're trying to use $n instead of a variable called $nth.

So you can do either of these:
code:
"this is the $($n)th thing"
"this is the ${n}th thing"
Something I use ${var} inside strings even when I don't have to, if I'm mashing to variables right next to each other for example, just to make it easier to read:

code:
$FirstThing = 'Thing1'
$SecondThing = 'Thing2'

"$FirstThing$SecondThing"
"${FirstThing}${SecondThing}"
Either of those work. Using $($JustAvariable) will technically have some kind of performance hit vs using the variable directly (with curly braces is still just using it directly), and even though it's going to be negligible it feels wrong to me, and is less legible.

When I must use a sub-expression, like for a property or method call, I often just end up assigning to a local variable instead so the string is nicer.

code:
"Here's your thing $($MyObj.Thing)" # meh

$myThing = $MyObj.Thing

"Here's your thing $myThing"

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

nielsm posted:

The former lets you concatenate with variable-name-valid characters right of the name.

E.g.: "Free space: $(variable)MB"
If you wrote "$variableMB" it would look for a variable actually named variableMB instead.

Actually, what it really does is let you put entire expressions inside an interpolated string, so you can do things like:
"Free space: $($freeSpace/$totalSpace*100)%"
Or you can check out the properties of those variables, like
code:
$var = get-aduser -filter * -properties *
foreach ($u in $var) {
  write-host "$($u.name)'s username is $($u.samaccountname) and their password was last changed on $($u.passwordlastset) and will expire on $($u.passwordlastset.adddays(90))"
}

anthonypants fucked around with this message at 17:36 on Jun 1, 2017

Irritated Goat
Mar 12, 2005

This post is pathetic.
Hm. Weird question.

I'm connecting to Exchange 2010 Powershell from my workstation. I can see my own mailbox via commands like Get-Mailbox. I can't seem to see anyone else's?

Does that make sense?

The script I'm using to connect is:

Function Connect-Exchange
{$credentials = Get-credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI [url]http://[/url]{Server}/powershell/ -Authentication kerberos
import-PSSession $session}

I'm using PS 4 if it makes some kind of difference.

nielsm
Jun 1, 2009



You're not passing the credential you prompt for to the Exchange session, so it gets logged in with the account you're running PowerShell under (probably your regular domain account).
If you need to use a different login to get administrative access, make sure you're actually passing $credentials to New-PSSession.

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
Yeah, change the first two lines of that function block to $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI [url]http://[/url]{Server}/powershell/ -Authentication kerberos -Credential (Get-Credential)

Irritated Goat
Mar 12, 2005

This post is pathetic.

nielsm posted:

You're not passing the credential you prompt for to the Exchange session, so it gets logged in with the account you're running PowerShell under (probably your regular domain account).
If you need to use a different login to get administrative access, make sure you're actually passing $credentials to New-PSSession.

:doh: I can't believe I missed something so simple.

anthonypants posted:

Yeah, change the first two lines of that function block to $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI [url]http://[/url]{Server}/powershell/ -Authentication kerberos -Credential (Get-Credential)

That'll work even better. Thanks.

Irritated Goat fucked around with this message at 17:19 on Jun 2, 2017

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
For what it's worth, you can preserve the $credential variable, but if you're not going to use it after that why leave a variable with your login credentials hanging around? One good use is if you want to connect to all the Office 365 services in one PowerShell window, but that's a different beast.

thebigcow
Jan 3, 2001

Bully!

thebigcow posted:

No.

Opening the PowerShell console takes almost exactly five seconds, the ISE loads near immediately. This is a new behavior since the last Windows Update that I haven't noticed until today because I guess I've been using the ISE for everything. I made a blank profile.ps1 to see if that was it and no dice. There is no profile.ps1 in $PSHOME. The x86 version loads almost immediately. :iiam:

I need to catch up on month end stuff before I can look into this again.

Update for the zero people that cared: It fixed itself after Windows Update installed some compatibility update.

Thom ZombieForm
Oct 29, 2010

I will eat you alive
I will eat you alive
I will eat you alive
Hey, complete novice, I've got a task to complete:

I’m creating calendar appointments for outlook using Exchange Web Service. Is “set extended property” a means for me to append my own id for later use on an appointment? I want to store a (string) member of an associated object when appointments are created so I can find them later for updates, but am not sure where to put it. Or should store in uiCaluid?

Bunni-kat
May 25, 2010

Service Desk B-b-bunny...
How can-ca-caaaaan I
help-p-p-p you?
I'm really sorry to ask this, but there's a jackhammer going on outside my window that's totally destroyed my ability to think.

I'm trying to get a list out of AD that has all the expired accounts listed. Not disabled, just expired. I'm using get-aduser, and the property accountexpires, but I can't figure out how to filter by dates. -eq {get-date}-1 does that sound right?

nielsm
Jun 1, 2009



Can't test right now, but basically something like -Filter "accountExpires -lt '2017-07-05'" should work.

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

Avenging_Mikon posted:

I'm really sorry to ask this, but there's a jackhammer going on outside my window that's totally destroyed my ability to think.

I'm trying to get a list out of AD that has all the expired accounts listed. Not disabled, just expired. I'm using get-aduser, and the property accountexpires, but I can't figure out how to filter by dates. -eq {get-date}-1 does that sound right?
You probably want to use AccountExpirationDate instead of accountExpires, and I'd use -lt (Get-Date) instead.
code:
Get-ADUser -Filter * -Properties AccountExpirationDate  |`
 Where-Object {($_.AccountExpirationDate -ne $null) -and ($_.AccountExpirationDate -lt (Get-Date))} |`
 Select-Object SamAccountName,AccountExpirationDate |`
 Sort-Object -Descending AccountExpirationDate
If you don't have AccountExpirationDate for whatever reason, you'll need to cast accountExpires as a datetime.
code:
Get-ADUser -Filter * -Properties accountExpires |`
 Where-Object {($_.accountExpires -ne '9223372036854775807') -and ($_.accountExpires -ne '0') -and ([datetime]::FromFileTime($_.accountExpires) -lt (Get-Date))} |`
 Select-Object SamAccountName,accountExpires |`
 Sort-Object -Descending accountExpires
There's other code to convert the accountExpires column to datetime but I always have to look it up and I hate doing it so don't do that unless you need to

anthonypants fucked around with this message at 18:10 on Jul 5, 2017

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy
NYC goons, I'm giving a talk at the PowerShell Meetup tonight. Come by if you're in the area.

I'll be talking about a module called Idempotion that I created for using DSC resources in scripts.

Inspector_666
Oct 7, 2003

benny with the good hair
I'll actually be able to make it back tonight! Hooray!

Wait crap no I can't :argh:

I swear I'll get to another meetup one of these days!

Inspector_666 fucked around with this message at 21:06 on Jul 10, 2017

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy

Inspector_666 posted:

I'll actually be able to make it back tonight! Hooray!

Wait crap no I can't :argh:

I swear I'll get to another meetup one of these days!
Ahh I was wondering where you were. In any case, check out the module!

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
I have a powershell script that automates some file backup, but the script has become slow as the number of files has grown - it's currently copying the entire working directory into the backup locations with each use, when it'd be better to just copy the new files.

IE, with the following files, it currently copies all five files, overwriting files 1, 2, and 3 in the backup directory, where it should be copying only file 4 and 5. (The files themselves don't change, so there's no worry that fileX in the backup directory will fall out of date).

code:
Working dir       Backup dir
-----             -----
file1             file1
file2             file2
file3             file3
file4
file5
The current one-liner is

code:
Copy-Item -Recurse -Force .\path\to\working\dir .\path\to\backup\dir
but I can't find any flag on the copy-item command that prevents clobbering existing files.

Suggestions?

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

Newf posted:

I have a powershell script that automates some file backup, but the script has become slow as the number of files has grown - it's currently copying the entire working directory into the backup locations with each use, when it'd be better to just copy the new files.

IE, with the following files, it currently copies all five files, overwriting files 1, 2, and 3 in the backup directory, where it should be copying only file 4 and 5. (The files themselves don't change, so there's no worry that fileX in the backup directory will fall out of date).

code:
Working dir       Backup dir
-----             -----
file1             file1
file2             file2
file3             file3
file4
file5
The current one-liner is

code:
Copy-Item -Recurse -Force .\path\to\working\dir .\path\to\backup\dir
but I can't find any flag on the copy-item command that prevents clobbering existing files.

Suggestions?
Use robocopy instead.

sloshmonger
Mar 21, 2013

Newf posted:

I have a powershell script that automates some file backup, but the script has become slow as the number of files has grown - it's currently copying the entire working directory into the backup locations with each use, when it'd be better to just copy the new files.

IE, with the following files, it currently copies all five files, overwriting files 1, 2, and 3 in the backup directory, where it should be copying only file 4 and 5. (The files themselves don't change, so there's no worry that fileX in the backup directory will fall out of date).

code:
Working dir       Backup dir
-----             -----
file1             file1
file2             file2
file3             file3
file4
file5
The current one-liner is

code:
Copy-Item -Recurse -Force .\path\to\working\dir .\path\to\backup\dir
but I can't find any flag on the copy-item command that prevents clobbering existing files.

Suggestions?

If you're adamant on using powershell, I think you can take out the -force flag and instead add -erroraction silentlycontinue

But the real answer is above my post.

Adbot
ADBOT LOVES YOU

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
If you use robocopy inside of PowerShell you can still use variable names as parts of the path or as excluded files/folders, so there's no* reason to use Copy-Item instead.

*Like the only reason I can think of where you might not want to use robocopy is because of its weird exit codes (e.g. inside of a Scheduled Task), but those are fairly well-documented, so you can write a wrapper around those or write them to a log somewhere if you really need to validate them.

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