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
Toshimo
Aug 23, 2012

He's outta line...

But he's right!
while(1) {gc -Wait "\\path\to\update.status" | Select-String "succeeded" | % {break}}

I'll show myself out.

Adbot
ADBOT LOVES YOU

Zaepho
Oct 31, 2013

The Fool posted:

((get-content "\\path\to\update.status") -eq "succeeded")

That's locked into an assumption of success. It should be checking for 'succeeded' or 'failed' at a minimum.

The Fool
Oct 16, 2003


PowerShell Unplugged with Jeffrey Snover and Don Jones
https://www.youtube.com/watch?v=D15vh-ryJGk


This is a fun video.

The Fool fucked around with this message at 20:11 on Sep 29, 2017

Pile Of Garbage
May 28, 2007



Anyone done XML validation against a schema in PowerShell? It looks somewhat straightforward using the .NET classes but but if anyone has a working sample that would be great!

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


What's the best Powershell or even Azure JSON Template Github? Aside from the official Microsoft ones which aren't bad but don't have specific use cases.

Briantist
Dec 5, 2003

The Professor does not approve of your post.
Lipstick Apathy
NYC PowerShell Meetup tonight. Serverless PowerShell using Azure functions, pretty cool stuff.

Methanar
Sep 26, 2013

by the sex ghost

Briantist posted:

NYC PowerShell Meetup tonight. Serverless PowerShell using Azure functions, pretty cool stuff.

Mostly off topic but I was in NYC for a holiday last week and I walked past this very building! I remember the Chevy's sign

The Fool
Oct 16, 2003


Briantist posted:

NYC PowerShell Meetup tonight. Serverless PowerShell using Azure functions, pretty cool stuff.

I am not in NY, otherwise I'd consider going.

I'm working on a project where one of the components is some logic done in Powershell, hosted as an Azure function, to manipulate a Sharepoint List via CSOM. It was really fun putting that together.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
Anyone going to the Powershell thing in Phoenix on the 14th?

thebigcow
Jan 3, 2001

Bully!
Is the -online option for Get-Help taking everyone else to a 404 page?

edit: Seems it's not everything.

Get-Command takes me here which works:

https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/Get-Command?view=powershell-4.0

Get-Childitem takes me here which 404s

https://docs.microsoft.com/en-us/powershell/module/4.0/microsoft.powershell.core/providers/FileSystem-Provider/Get-ChildItem-for-Filesystem

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

thebigcow posted:

Is the -online option for Get-Help taking everyone else to a 404 page?

edit: Seems it's not everything.

Get-Command takes me here which works:

https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/Get-Command?view=powershell-4.0

Get-Childitem takes me here which 404s

https://docs.microsoft.com/en-us/powershell/module/4.0/microsoft.powershell.core/providers/FileSystem-Provider/Get-ChildItem-for-Filesystem
If you change it from 4.0 to 3.0 it'll redirect to the correct link, which doesn't have the version number in it at all:
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/providers/filesystem-provider/get-childitem-for-filesystem

anthonypants fucked around with this message at 23:50 on Oct 16, 2017

thebigcow
Jan 3, 2001

Bully!
Neato. I don't know where to file a bug for this.

The Fool
Oct 16, 2003


https://github.com/powershell


edit: lol, anthonypants already submitted it: https://github.com/PowerShell/PowerShell/issues/5136

edit2: because I'm bored
code:
        /// <summary>
        /// This parameter,if true, will direct get-help cmdlet to
        /// navigate to a URL (stored in the command MAML file under
        /// the uri node).
        /// </summary>

The Fool fucked around with this message at 17:48 on Oct 17, 2017

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin

I guess I've got to learn this stupid new git thing that all the cool kids are talking about.

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

The Fool posted:

https://github.com/powershell


edit: lol, anthonypants already submitted it: https://github.com/PowerShell/PowerShell/issues/5136

edit2: because I'm bored
code:
        /// <summary>
        /// This parameter,if true, will direct get-help cmdlet to
        /// navigate to a URL (stored in the command MAML file under
        /// the uri node).
        /// </summary>
It looks like it might be fixed in the GitHub repo, which points to https://go.microsoft.com/fwlink/?LinkID=113308, it's just not fixed in 5.1.

thebigcow
Jan 3, 2001

Bully!
Thank you!

Roargasm
Oct 21, 2010

Hate to sound sleazy
But tease me
I don't want it if it's that easy

Irritated Goat posted:

Ok. Help me believe I'm not insane.

I'm using the NTFSSecurity module to assign Domain Users permissions to a folder.

code:
Import-Module NTFSSecurity
New-Item -type directory -path <local location for app>
Copy-Item <network location of app> <local location of app>
Get-item .\App | Add-NTFSAccess -Account "Domain\Domain Users" -AccessRights Modify
When it hits the Add-NTFSAccess portion, I get an access denied. I'm local admin on this PC so I'm confused as to why I'd even run into this issue. :confused:

The script basically just
    creates a folder
    copies the network install of it to the newly created folder
    Gives domain\domain users modify access on it as the application auto-updates itself

I ran into issues with ACL permission scripts because they were also trying to set the file owner, which was throwing access denied. Been a year or so since I've used it but I'm pretty sure this worked for NTFS perms:
code:
foreach ($folder in $folders) {
$newPerms = "MYCORP\Domain Users",'Modify,Synchronize','ContainerInherit, ObjectInherit', 'InheritOnly', 'Allow'
$newAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $newPerms
$myACL = (Get-Item $folder.FullName).GetAccessControl('Access')
$myACL.SetAccessRule($newAccessRule)
$myACL | Set-ACL $folder.FullName
}
docs: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemaccessrule(v=vs.110).aspx

nielsm
Jun 1, 2009



I'm wondering if there are some idioms or syntaxes I'm missing, working with the regular MS ActiveDirectory module.

Say I have a list of user names, and a list of group names. I want to know what users are not in each group, and I want to simply add the missing users. Using Add-ADGroupMember with -Members @("user1", "user2") fails if even a single of the users is already member of the group, and making a loop (ForEach-Object) over the users is awkward and seems backward. Is there a better way?

Is there a good way to present a table (matrix) of AD user objects (with MemberOf property fetched) with some select groups as columns, containing member true/false flags? One that doesn't involve a loop and Add-Member (or creating PSCustomObjects).

The Claptain
May 11, 2014

Grimey Drawer

nielsm posted:

I'm wondering if there are some idioms or syntaxes I'm missing, working with the regular MS ActiveDirectory module.

Say I have a list of user names, and a list of group names. I want to know what users are not in each group, and I want to simply add the missing users. Using Add-ADGroupMember with -Members @("user1", "user2") fails if even a single of the users is already member of the group, and making a loop (ForEach-Object) over the users is awkward and seems backward. Is there a better way?

Is there a good way to present a table (matrix) of AD user objects (with MemberOf property fetched) with some select groups as columns, containing member true/false flags? One that doesn't involve a loop and Add-Member (or creating PSCustomObjects).

I'm phone posting, so I can't check this, but you could probably use Compare-Object cmdlet on outputs of Get-ADUser and Get-ADGroupMember, which should return you a list of users that are not in a specified group.

Something like:
code:
$ADUsers = Get-ADUser...
$GroupMembers = Get-ADGroupMember...
$UsersToAdd = Compare-Object -referenceObject $ADUsers -differenceObject $GroupMembers
You can also use -passThru parameter of Compare-Object to pass the object created to the pipeline if for some reason you do not want it stored in the variable.

The Claptain fucked around with this message at 13:21 on Nov 14, 2017

Pile Of Garbage
May 28, 2007



nielsm posted:

I'm wondering if there are some idioms or syntaxes I'm missing, working with the regular MS ActiveDirectory module.

Say I have a list of user names, and a list of group names. I want to know what users are not in each group, and I want to simply add the missing users. Using Add-ADGroupMember with -Members @("user1", "user2") fails if even a single of the users is already member of the group, and making a loop (ForEach-Object) over the users is awkward and seems backward. Is there a better way?

Is there a good way to present a table (matrix) of AD user objects (with MemberOf property fetched) with some select groups as columns, containing member true/false flags? One that doesn't involve a loop and Add-Member (or creating PSCustomObjects).

I find it's easiest to compare arrays of common attribute value types with the -in / -notin comparison operators. Assuming you have two text-files with lists of users and groups something like this should work (The member AD attribute contains an array of all group members referenced by their distinguished name):

code:
$Users = Get-Content -Path 'C:\Temp\UserList.txt' | Get-ADUser
$Groups = Get-Content -Path 'C:\Temp\GroupList.txt' | Get-ADGroup -Properties member

foreach ($Group in $Groups) {
    Add-ADGroupMember -Identity $Group -Members ($Users | ? { $_.DistinguishedName -notin $Group.Member })
}

The Claptain posted:

I'm phone posting, so I can't check this, but you could probably use Compare-Object cmdlet on outputs of Get-ADUser and Get-ADGroupMember, which should return you a list of users that are not in a specified group.

I've found that using Compare-Object can be difficult as differences in object member sets can throw it off. It's usually easier to just compare arrays of strings.

Hughmoris
Apr 21, 2007
Let's go to the abyss!
I need some help with getting powershell to display glyphs correctly. I'll preface this by saying I don't have a great grasp on fonts/glyphs/unicode.

I'm using powershell to execute some Perl 6 code. It is not properly displaying glyphs that are in the output. After some googling, I've installed Unifont and am using the Powershell ISE but it still fails to display properly. Here is what the output looks like:



Any ideas?

The Fool
Oct 16, 2003


Try ConEmu

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

I'll give that a look. Thanks!

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
PowerShell doesn't have problems parsing unicode, it looks like that's a problem with perl.

Wicaeed
Feb 8, 2005
Is there a way to break up a single line powershell command across multiple lines, allowing for easier readability, but still being able to copy/paste it directly into a Powershell prompt?

I've got something like
code:
Register-ScheduledTask ^
    -TaskName "TestRail Background Task" ^
    -Trigger (-Once -At (Get-Date) -RepetitionInterval (New-Timespan -Minutes 1) -RepetitionDuration ([System.TimeSpan]::MaxValue)) ^
    -Action (New-ScheduledTaskAction -Execute "C:\Program Files (x86)\PHP\v5.6\php.exe" -Argument "E:\TestRail\task.php") ^
    -Settings (New-ScheduledTaskSettingsSet -AsJob -ExecutionTimeLimit 1h -MultipleInstances StopExisting) ^
    -RunLevel ^
But that doesn't seem to work, but according to Google that's how you do it

The Fool
Oct 16, 2003


Use backtick `

not caret ^

nielsm
Jun 1, 2009



Or splat it:
code:
$taskArgs = @{
    TaskName = "TestRail Background Task"
    Trigger = (New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-Timespan -Minutes 1) -RepetitionDuration ([System.TimeSpan]::MaxValue))
    Action = (New-ScheduledTaskAction -Execute "C:\Program Files (x86)\PHP\v5.6\php.exe" -Argument "E:\TestRail\task.php")
    Settings = (New-ScheduledTaskSettingsSet -AsJob -ExecutionTimeLimit 1h -MultipleInstances StopExisting)
}
Register-ScheduledTask @taskArgs

Inspector_666
Oct 7, 2003

benny with the good hair

nielsm posted:

Or splat it:
code:
$taskArgs = @{
    TaskName = "TestRail Background Task"
    Trigger = (New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-Timespan -Minutes 1) -RepetitionDuration ([System.TimeSpan]::MaxValue))
    Action = (New-ScheduledTaskAction -Execute "C:\Program Files (x86)\PHP\v5.6\php.exe" -Argument "E:\TestRail\task.php")
    Settings = (New-ScheduledTaskSettingsSet -AsJob -ExecutionTimeLimit 1h -MultipleInstances StopExisting)
}
Register-ScheduledTask @taskArgs

Do this, it's the preferred method to ` from everything I found.

Pile Of Garbage
May 28, 2007



Inspector_666 posted:

Do this, it's the preferred method to ` from everything I found.

As long as you do it with hash tables and not arrays. IMO you should always be using named parameters for cmdlets. It's far less ambiguous and less likely to break compared to using positional parameters.

Jowj
Dec 25, 2010

My favourite player and idol. His battles with his wrists mirror my own battles with the constant disgust I feel towards my zerg bugs.
Seconding splatting - it makes poo poo so much easier to read.

The Iron Rose
May 12, 2012

:minnie: Cat Army :minnie:
Question guys, that's hopefully basic.

I have a script that grabs a CSV of all detected AV threats from the web, saves it to $output, sorts it, selects certain columns, than bundles those off into HTML and emails it.

There's a certain column in the CSV, which is called "Last Found." In that column, it simply lists the date that the threat was last found, in the following format: MM/DD/YYYY HH/MM. An example would be "1/12/2018 19:16"


What I want to do is compare that against the current date, and remove all rows where "Last Found" is over a week from the current date. I think the way I want to do this is something like what I have below:

code:
Get-Content $output | Where{$_ -notmatch $date} | Out-File $output
But for the life of me I can't figure out how to compare the current date against the date under "Last Found" and strip out rows older than 7 days as a result.


Once that's done, I just call the rest of my script like normal. Relevant bits below:

The relevant command:
code:
$csv = Import-Csv $output | sort "Last Found" | Select "File Name",DeviceName,"Last Found", "File Path" | ConvertTo-Html -head $a -Body @"
"@
One other thing to note - I don't know poo poo about powershell :v: and I'm mostly just learning by doing, well, things like this at work. Any pointers would be greatly appreciated.

Sefal
Nov 8, 2011
Fun Shoe
I'm leaving the office now, But I just wanna say. You should give the book "Powershell in a month of lunches" a read.
It's a great book.

Edit: Really quickly at the top of my head. Would something like
(Get-Date).AddDays(-7)
work?

Sefal fucked around with this message at 18:02 on Jan 15, 2018

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

The Iron Rose posted:

in the following format: MM/DD/YYYY HH/MM. An example would be "1/12/2018 19:16"

Just to be clear, which format is it, because the format you posted and the date you posted, are not the same in several ways.

The Fool
Oct 16, 2003


Sefal posted:

I'm leaving the office now, But I just wanna say. You should give the book "Powershell in a month of lunches" a read.
It's a great book.

Edit: Really quickly at the top of my head. Would something like
(Get-Date).AddDays(-7)
work?

I’m phone posting so it’s not easy to post some sample code, but this is the right direction.

You need to convert your date strings into date-time objects, subtract 7 days from the current date, then you can do direct comparisons and filter using where-object.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date

The Iron Rose posted:

One other thing to note - I don't know poo poo about powershell :v: and I'm mostly just learning by doing, well, things like this at work. Any pointers would be greatly appreciated.

One liners are only good for e-penis competitions and copy-pasting. If you are writing scripts to be saved and reused, be as verbose as is practical so that it is easier to go back and maintain your poo poo afterwards.



The Fool fucked around with this message at 18:18 on Jan 15, 2018

Pile Of Garbage
May 28, 2007



The Iron Rose posted:

Question guys, that's hopefully basic.

I have a script that grabs a CSV of all detected AV threats from the web, saves it to $output, sorts it, selects certain columns, than bundles those off into HTML and emails it.

There's a certain column in the CSV, which is called "Last Found." In that column, it simply lists the date that the threat was last found, in the following format: MM/DD/YYYY HH/MM. An example would be "1/12/2018 19:16"


What I want to do is compare that against the current date, and remove all rows where "Last Found" is over a week from the current date. I think the way I want to do this is something like what I have below:

code:
Get-Content $output | Where{$_ -notmatch $date} | Out-File $output
But for the life of me I can't figure out how to compare the current date against the date under "Last Found" and strip out rows older than 7 days as a result.


Once that's done, I just call the rest of my script like normal. Relevant bits below:

The relevant command:
code:
$csv = Import-Csv $output | sort "Last Found" | Select "File Name",DeviceName,"Last Found", "File Path" | ConvertTo-Html -head $a -Body @"
"@
One other thing to note - I don't know poo poo about powershell :v: and I'm mostly just learning by doing, well, things like this at work. Any pointers would be greatly appreciated.

Assuming the date in the "Last Found" column is well-formed you can use a filter like this:

code:
[System.DateTime]::Parse($_.'Last Found') -gt (Get-Date).AddDays(-7)
Also if you're pulling the data and then processing it in the same script you should just pass it around as an object instead of exporting and re-importing it.

The Fool
Oct 16, 2003


code:
$output = $output | Where-Object ((Get-Date ($_.'Last Found')) -gt ((Get-Date).AddDays(-7)))
This is how I would do it, but this is completely untested.

Pile Of Garbage
May 28, 2007



The Fool posted:

code:
$output = $output | Where-Object ((Get-Date ($_.'Last Found')) -gt ((Get-Date).AddDays(-7)))
This is how I would do it, but this is completely untested.

Jeez you've gone a bit overboard with the brackets there mate. Also script blocks should be contained in curly brackets:

code:
$output = $output | Where-Object { (Get-Date $_.'Last Found') -gt (Get-Date).AddDays(-7) }

The Fool
Oct 16, 2003


Yeah, I mess up the curly braces all the loving time and did nothing to valid the snippet I posted.

The Iron Rose
May 12, 2012

:minnie: Cat Army :minnie:

The Fool posted:

I’m phone posting so it’s not easy to post some sample code, but this is the right direction.

You need to convert your date strings into date-time objects, subtract 7 days from the current date, then you can do direct comparisons and filter using where-object.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date


One liners are only good for e-penis competitions and copy-pasting. If you are writing scripts to be saved and reused, be as verbose as is practical so that it is easier to go back and maintain your poo poo afterwards.

Yep, this is the direction I'm heading in. Forgetting about the rest of what I need my script to do, right now I'm just trying to get the compare working.

So I wrote this up for testing.

code:
$OneDayLess = "{0:MM/dd/yyyy}" -f (get-date).AddDays(-3)
$output = "$PWD\ThreatsDataReport.csv"

Write-Host $OneDayLess

import-csv $output | Where-Object {$_."Last Found" -match "$OneDayLess.*"} | export-csv $PWD\test.txt
This correctly saves $OneDayLess as 1/12/2018. In my CSV, I have a known quantity of "1/12/2018 2:24" as a string in the CSV under "Last Found." And yet I can't output the row in question to my test.txt


E: Wow I need to refresh before posting more, thank you all so much!

cheese-cube posted:

Jeez you've gone a bit overboard with the brackets there mate. Also script blocks should be contained in curly brackets:

code:
$output = $output | Where-Object { (Get-Date $_.'Last Found') -gt (Get-Date).AddDays(-7) }

This one looks real neat, and I think the -gt flag is what I want to use in this case! That's way easier than doing individual variables for every single day I want to go back a la the snippet I posted above. I think I need to understand what it's doing exactly before trying to integrate it into the rest.

It looks like it's taking $output (which is the ThreatsDataReport.csv), piping it to Where-Object, where it looks like it's trying to get the date from "Last Found". Subsequently, the -gt flag is meant to ensure that the rows are greater than the current date minus 7 days are passed back to $output.

I think I have that correct at any rate! The problem here is that a) I'm not sure that it's matching correctly thanks to the drat time appended to the date in the .CSV, and b) this is just storing the rows to $output, right? Not an actual .csv I can then call with import-csv (which is what I use to sort, select certain columns, and convert to HTML.

Actually hell with it, I'll just post the rest of the script.

code:
#Converts ThreatsDataReport.csv to ignore data over 7 days
$output = $output | Where-Object { (Get-Date $_.'Last Found') -gt (Get-Date).AddDays(-7) }


$csv = Import-Csv $output | sort "Last Found" | Select "File Name",DeviceName,"Last Found", "File Path" | ConvertTo-Html -head $a -Body @"
"@
#Imports the CSV saved to $output, selects the File Name, Device Name, and File Path, converts to HTML using the Head +Body Information
$emailBody = "$csv"

#defines the body text of the email. Note that this has to be a string, $emailBody = $csv will not work on its own. 

Send-MailMessage -From $emailFrom -To $emailRecipients -SmtpServer $emailSMTPServer -subject $emailSubject -Body $emailBody -BodyAsHtml
#Sends the actual email
If I get rid of the Import-CSV argument and am just calling $csv = $output etc etc, nothing comes up when I then save $csv into a string that I then paste in the email body.


If I do something like:

code:
$output = $output | Where-Object { (Get-Date $_.'Last Found') -gt (Get-Date).AddDays(-7) }

$output | export-csv $PWD\test.txt
Nothing comes up in the resultant .txt, which sounds to me like it's not matching correctly.

E: gonna take a breather for now, do some more research, and come back with some better questions. Thanks for all y'all's help so far, it's very appreciated.

The Iron Rose fucked around with this message at 19:15 on Jan 15, 2018

Adbot
ADBOT LOVES YOU

Pile Of Garbage
May 28, 2007



As others have mentioned the main difficulty you might have is casting that "Last Found" value as a DateTime object. That depends entirely on whether or not it's well formed which will become apparent as soon as you run the script (I'm pretty sure Get-Date calls the Parse() method of System.DateTime if you pass it a string which will throw an exception if it can't parse it).

Of course if it does parse as a DateTime object then you can go hog-wild with comparing it to other DateTime objects, amongst other things.

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