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
Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

Had a fun thing that I nearly came into this thread to ask about. I've been using the type three letters then tab autocomplete in PowerShell ISE to run my various .ps1's. Turns out it will pick other extensions first if they have the same name... I was wondering why that .CSV file kept opening in excel every time I tried to run the script!

Adbot
ADBOT LOVES YOU

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


Can anyone explain the reasoning why if Invoke-WebRequest or Invoke-RestMethod are successful, you can check $response.StatusCode but if it encounters an error like a 4xx/5xx you need to look at $_.Exception.Response.StatusCode.Value__?
I just had a colleague "fix" a script I wrote by taking the Value__ from my catches and use it on status code checks on the not-exceptional responses as well.
:argh:

Mario
Oct 29, 2006
It's-a-me!
Can only guess why it was designed that way, but your observation is because the cmdlet throws an exception (and never writes the response back to your variable). The exception throw can be disabled in PowerShell 7 and the PR for it offers some insight.

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




I have 50 security groups that I need to add 2 users to the Delivery Management list so they can send to all of them. They're all in the format companyname.office.cityname, is it possible to add user1@company.com and user2@company.com to the allowed senders for companyname.office.* ?

Submarine Sandpaper
May 27, 2007


TITANKISSER69 posted:

I have 50 security groups that I need to add 2 users to the Delivery Management list so they can send to all of them. They're all in the format companyname.office.cityname, is it possible to add user1@company.com and user2@company.com to the allowed senders for companyname.office.* ?

if I"m reading right:

Set-Mailbox -Identity "Robin Wood" -AcceptMessagesOnlyFrom "Lori Penor","Jeff Phillips" -AcceptMessagesOnlyFromDLMembers "Legal Team 1"

https://docs.microsoft.com/en-us/exchange/recipients/user-mailboxes/message-delivery-restrictions?view=exchserver-2019

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




Submarine Sandpaper posted:

if I"m reading right:

Set-Mailbox -Identity "Robin Wood" -AcceptMessagesOnlyFrom "Lori Penor","Jeff Phillips" -AcceptMessagesOnlyFromDLMembers "Legal Team 1"

https://docs.microsoft.com/en-us/exchange/recipients/user-mailboxes/message-delivery-restrictions?view=exchserver-2019

I'm thinking it would be more like the example linked here: https://community.spiceworks.com/topic/2232835-remove-member-from-delivery-management-with-exhange-powershell

quote:

Set-DistributionGroup "GROUP-NAME-HERE" -AcceptMessagesOnlyFromSendersOrMembers((Get-DistributionGroup "GROUP-NAME-HERE").AcceptMessagesOnlyFromSendersOrMembers + "IDENTITY-OF-USER-OR-GROUP-HERE")

The trick is I'm hoping I can literally enter companyname.office.* so all of the groups can be updated at once.

Inspector_666
Oct 7, 2003

benny with the good hair

TITANKISSER69 posted:

I'm thinking it would be more like the example linked here: https://community.spiceworks.com/topic/2232835-remove-member-from-delivery-management-with-exhange-powershell


The trick is I'm hoping I can literally enter companyname.office.* so all of the groups can be updated at once.

I'm not sure if you can wildcard that line, but you should be able to use Get-DistributionGroup -Filter or maybe -Anr to put the list into a variable you can then go through with a ForEach loop.

Pile Of Garbage
May 28, 2007



Inspector_666 posted:

I'm not sure if you can wildcard that line, but you should be able to use Get-DistributionGroup -Filter or maybe -Anr to put the list into a variable you can then go through with a ForEach loop.

The Identity parameter of Set-DistributionGroup accepts value from pipeline input so you can just pipe Get-DistributionGroup straight into it instead of using a loop (Make sure to run your Get-DistributionGroup command separately first to validate the output before piping it through).

mllaneza
Apr 28, 2007

Veteran, Bermuda Triangle Expeditionary Force, 1993-1952




e. Didn't read the last post.

Antigravitas
Dec 8, 2019

Die Rettung fuer die Landwirte:
I just rediscovered Powershell can do pass by reference.

Oh yeah, it's coding horror time :cool:

Dirt Road Junglist
Oct 8, 2010

We will be cruel
And through our cruelty
They will know who we are

Antigravitas posted:

I just rediscovered Powershell can do pass by reference.

Oh yeah, it's coding horror time :cool:

Oh fuuuuuuuuuun.

mystes
May 31, 2006

Antigravitas posted:

I just rediscovered Powershell can do pass by reference.

Oh yeah, it's coding horror time :cool:
It has to be able to for .net compatibility.

captaingimpy
Aug 3, 2004

I luv me some pirate booty, and I'm not talkin' about the gold!
Fun Shoe
I'm doing something dumb, but can't figure out exactly what it is (been a few years since I've worked with PS)

I'm looping through a file to set variables. Some of them I need to convert to SecureString. The ones that are converted to SecureString lose their value at the end of the loop where the ones that aren't don't. Any help would be appreciated.


code:
param ([SecureString] $username,[SecureString] $password,$blah1,$blah2,[SecureString] $blah3,[SecureString] $blah4,[SecureString] $blah343,$groupIDs,$blah33,$name)


$varFile = $PSScriptRoot + "/var.txt"

if (Test-Path $varFile -PathType leaf){
Get-Content $varFile| Foreach-Object{
    $var = $_.Split('=')
    if (($var[0] -eq "username") -or ($var[0] -eq "password")){
        $var[0] = ConvertTo-SecureString $var[1] -AsPlainText -Force
        } else {
        Set-Variable -Name $var[0] -Value $var[1]
        }
}
}

Zaepho
Oct 31, 2013

Twat Waffle posted:

I'm doing something dumb, but can't figure out exactly what it is (been a few years since I've worked with PS)

I'm looping through a file to set variables. Some of them I need to convert to SecureString. The ones that are converted to SecureString lose their value at the end of the loop where the ones that aren't don't. Any help would be appreciated.


code:
param ([SecureString] $username,[SecureString] $password,$blah1,$blah2,[SecureString] $blah3,[SecureString] $blah4,[SecureString] $blah343,$groupIDs,$blah33,$name)


$varFile = $PSScriptRoot + "/var.txt"

if (Test-Path $varFile -PathType leaf){
Get-Content $varFile| Foreach-Object{
    $var = $_.Split('=')
    if (($var[0] -eq "username") -or ($var[0] -eq "password")){
        $var[0] = ConvertTo-SecureString $var[1] -AsPlainText -Force
        } else {
        Set-Variable -Name $var[0] -Value $var[1]
        }
}
}

You're not creating the variable you're expecting to in the case of Username or Password. When you're trying to create the new variable you're just overwriting the 0 index of the $var array. Try changing that line to:
code:
Set-Variable -Name $var[0] -Value (ConvertTo-SecureString $var[1] -AsPlainText -Force)

captaingimpy
Aug 3, 2004

I luv me some pirate booty, and I'm not talkin' about the gold!
Fun Shoe
Thanks for the explanation and help! It is very much appreciated.

I had tried using the Set-Variable bit and couldn't get the convertto-securestring to work as I was passing it incorrectly.

MJP
Jun 17, 2007

Are you looking at me Senpai?

Grimey Drawer
Okay, I need to take a basics of computer programming course because when I'm trying to do what every other person in my area seems to be able to do without even blinking, I completely struggle with, and I don't know the right terms or way to google what I need.

I need some help on this, and please I beg of you, put it in high school level terms, because I'm trying really hard to catch up beyond simple one-line scripts.

When I run the script herein, it doesn't even do anything. It just enters onto the next line, nothing. Even with -whatif. I ran $writeverbose="continue" in the terminal in hopes that I could just get it to show me everything it's doing, but it still does nothing.

How do I tell a script to just dump everything into a console so I can troubleshoot what I'm doing and at least try to learn?

code:
$subscriptionguids=(import-csv H:\Billing\Subscriptionguids.csv)
foreach ($subscriptionguid in $subscriptionguidss) 
{remove-azroleassignment -signinname "overprovisioned.user@company.com" -RoleDefinitionName "Owner" -Scope "/subscriptions/$subscriptionguids"}

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


MJP posted:

Okay, I need to take a basics of computer programming course because when I'm trying to do what every other person in my area seems to be able to do without even blinking, I completely struggle with, and I don't know the right terms or way to google what I need.

I need some help on this, and please I beg of you, put it in high school level terms, because I'm trying really hard to catch up beyond simple one-line scripts.

When I run the script herein, it doesn't even do anything. It just enters onto the next line, nothing. Even with -whatif. I ran $writeverbose="continue" in the terminal in hopes that I could just get it to show me everything it's doing, but it still does nothing.

How do I tell a script to just dump everything into a console so I can troubleshoot what I'm doing and at least try to learn?

code:
$subscriptionguids=(import-csv H:\Billing\Subscriptionguids.csv)
foreach ($subscriptionguid in $subscriptionguidss) 
{remove-azroleassignment -signinname "overprovisioned.user@company.com" -RoleDefinitionName "Owner" -Scope "/subscriptions/$subscriptionguids"}

Without giving any thought to what you're asking, I see you have a typo:
($subscriptionguid in $subscriptionguidss)

Zaepho
Oct 31, 2013

MJP posted:

How do I tell a script to just dump everything into a console so I can troubleshoot what I'm doing and at least try to learn?

code:
$subscriptionguids=(import-csv H:\Billing\Subscriptionguids.csv)
foreach ($subscriptionguid in $subscriptionguidss) 
{remove-azroleassignment -signinname "overprovisioned.user@company.com" -RoleDefinitionName "Owner" -Scope "/subscriptions/$subscriptionguids"}

Write-Host is your friend.
code:
[array]$subscriptionguids=(import-csv H:\Billing\Subscriptionguids.csv)
write-host "Found $($subscriptionguids.Count) GUIDS to process"
foreach ($subscriptionguid in $subscriptionguids)  {
	Write-host $subscriptionguid 
	remove-azroleassignment -signinname "overprovisioned.user@company.com" -RoleDefinitionName "Owner" -Scope "/subscriptions/$subscriptionguids"
}
Also, by using Import-CSV you're getting an object with a property for each field of the CSV file. However, you're treating it as a single string. This is probably not going to work the way you expect it to.

MJP
Jun 17, 2007

Are you looking at me Senpai?

Grimey Drawer

Zaepho posted:

by using Import-CSV you're getting an object with a property for each field of the CSV file

So if what I want to do is make $subscriptionguid a variable that uses the next GUID in the array, what should I use if not import-csv? https://lukesalter.wordpress.com/2014/06/12/powershell-read-a-csv-file-into-an-array/ seems to indicate that import-csv is what I should use.

mllaneza
Apr 28, 2007

Veteran, Bermuda Triangle Expeditionary Force, 1993-1952




Nth Doctor posted:

Without giving any thought to what you're asking, I see you have a typo:
($subscriptionguid in $subscriptionguidss)

Fix this first, then keep asking questions if that wasn't the only thing wrong.

Submarine Sandpaper
May 27, 2007


if your csv/text file is something like

1337
6969
420


then use get-content

eonwe
Aug 11, 2008



Lipstick Apathy

Toast Museum posted:

PowerShell Scripting in a Month of Lunches by the same authors. Formerly called PowerShell Toolmaking in a Month of Lunches. Full disclosure, I got sidetracked by actual scripting projects and never finished this one, but it seems like a good resource.

Edit: also, see if you have access to something like LinkedIn Learning (formerly Lynda) or Pluralsight through your employer, local library, etc. In my county, for instance, anyone with a library card has free access to LinkedIn Learning, and not just on-site.

Thanks I needed this

Djimi
Jan 23, 2004

I like digital data

mllaneza posted:

If that's a copy n' paste of all your code, there's your problem. You've got one reference to $extx, which has an assigned value, and one to $ext which doesn't.

Not all the code, just two lines. Line above was xls extension.
Sorry - I have been too busy at work to check the forum. Thanks for the help though everyone, I got what I needed. :v:

BeastOfExmoor
Aug 19, 2003

I will be gone, but not forever.
Is anyone aware of a way to have Powershell interact with a SSH session that's compatible with Powershell Core? I'm updating a team member's script which used Posh-SSH, but in troubleshooting some errors I was having I found out Posh-SSH only works with Desktop and not Core at this point and it seems kind of dumb to develop script limited to Desktop in 2020.

Potato Salad
Oct 23, 2014

nobody cares


are you basically looking for MS expect ?

BeastOfExmoor
Aug 19, 2003

I will be gone, but not forever.

Potato Salad posted:

are you basically looking for MS expect ?

I had to look up Expect, but that's not really what I was looking for. I have some devices which can take API commands over SSH and I wanted to send some commands and evaluate what they return in order to validate some testing. This was fairly straightforward with Posh-SSH, but I didn't want to be stuck with Desktop. Fortunately they can also take HTTP API calls, so I think I'm just going to have to go in that direction.

mystes
May 31, 2006

BeastOfExmoor posted:

I had to look up Expect, but that's not really what I was looking for. I have some devices which can take API commands over SSH and I wanted to send some commands and evaluate what they return in order to validate some testing. This was fairly straightforward with Posh-SSH, but I didn't want to be stuck with Desktop. Fortunately they can also take HTTP API calls, so I think I'm just going to have to go in that direction.
If you just need to run a single command, you should be able to just pass it to the ssh client exe and get the result back.

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




What command can I use to generate a list of mailboxes that one employee has Send As permission on?

The Fool
Oct 16, 2003


A single command won't do it, but two commands piped together will

code:
Get-Mailbox | Get-RecipientPermission -Trustee $user
This queries all mailboxes when run, so it can take a minute. If you need to do this for a bunch of users at once, you should cache the get-mailbox results and loop over that.

Also, if you have more than 1000 mailboxes, you will want to specify ResultSize

https://docs.microsoft.com/en-us/powershell/module/exchange/get-mailbox?view=exchange-ps
https://docs.microsoft.com/en-us/powershell/module/exchange/get-recipientpermission?view=exchange-ps

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




That's showing me FullAccess, but not Send As

Thirteenth Step
Mar 3, 2004

code:
Get-Mailbox | Get-RecipientPermission -AccessRights SendAs -Trustee $User
I'm new to Powershell so this may be totally wrong but maybe that?

The Fool
Oct 16, 2003


Get-RecipientPermission should only work for SendAs permissions.

If you are checking for other permissions, you would use Get-MailboxPermission

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




code:
PS C:\Users\TK69> Get-Mailbox | Get-RecipientPermission -Trustee USERNAME
Get-RecipientPermission : The term 'Get-RecipientPermission' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was 
included, verify that the path is correct and try again.
At line:1 char:15
+ Get-Mailbox | Get-RecipientPermission -Trustee USERNAME
+               ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-RecipientPermission:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

The Fool
Oct 16, 2003


I suppose I assumed and did not ask.

Get-RecipientPermission is O365 only and will not work with on-prem exchange.

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




My bad, I should have stated that up front

The Fool
Oct 16, 2003


A quick google found me this: https://www.beaming.co.uk/knowledge-base/powershell-commands-view-mailbox-permissions-migrating-exchange-server/

Where you need to query ad extended permissions to get what you're looking for.

Not something I've ever tried to do though.

nielsm
Jun 1, 2009



Depends on the Exchange version, really. As far as I understand the extended AD permission is what Exchange 2007 did, and some update to 2013 changed it to be a MailboxPermission, while still accepting the AD permission. But O365 is always the RecipientPermission.

nielsm
Jun 1, 2009



Question time: Question and answer time:
I'm writing a script module to wrap a web service. Some parts of the web service don't have great lookup features yet, so to find an object by e.g. display name I have to fetch all objects of the class and then filter them myself.

I have something like this:
code:
function Get-Thingy{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$False, ValueFromPipeline=$True, Position=0, ParameterSetName="Single")] $Thingy,
        [Parameter(Mandatory=$False, ParameterSetName="ByName")] [string] $DisplayName,
        [Parameter(Mandatory=$False, ParameterSetName="ByFrob")] [string] $FrobsWith,
        [Parameter(Mandatory=$False, ParameterSetName="All")] [switch] $All
    )
    Process {
        if ($PSCmdlet.ParameterSetName -eq "Single") {
            $ThingyGuid = [GUID]::Empty
            if ($Thingy.GetType().FullName -eq "System.Guid") {
                $ThingyGuid = $Thingy
            } elseif ($Thingy.Uid) {
                $ThingyGuid = [GUID]$Thingy.Uid
            } elseif ([GUID]::TryParse($Thingy, [ref]$ThingyGuid)) {
            }
            if ($ThingyGuid -ne [GUID]::Empty) {
                Invoke-RestMethod -UseDefaultCredentials  -Uri "$script:UrlBase/api/v1/thingy/$ThingyGuid" -Method GET
            }
        } elseif ($PSCmdlet.ParameterSetName -eq "ByName") {
            Get-Thingy -All | Where DisplayName -like $DisplayName
        } elseif ($PSCmdlet.ParameterSetName -eq "ByFrob") {
            Get-Thingy -All | Where FrobsWith -like $FrobsWith
        } elseif ($All) {
            Invoke-RestMethod -UseDefaultCredentials  -Uri "$script:UrlBase/api/v1/thingy" -Method GET
        }
    }
}
It works with the Single and All parameter sets when used by itself.
But when I try the ByName or ByFrob parameter set I get nothing back.

Fake edit: I found the answer while writing this post, so leaving it here so anyone else can maybe learn too.
The issue is that Invoke-RestMethod technically returns a object[] array instead of a PowerShell collection or PSCustomObject, when the web service call returns a JSON array.
You need to do "something" to the result to force it to convert into a regular PowerShell collection of PSCustomObject data. One thing you can do is simply wrap the call in parentheses, like this:
code:
(Invoke-RestMethod -UseDefaultCredentials  -Uri "$script:UrlBase/api/v1/thingy" -Method GET)
Tada now everything works.

By the way this is on PowerShell 5.1.17763.1007 on Windows 10 1809. Maybe it's fixed/improved in the newer versions.

Toast Museum
Dec 3, 2005

30% Iron Chef

nielsm posted:

Fake edit: I found the answer while writing this post, so leaving it here so anyone else can maybe learn too.
The issue is that Invoke-RestMethod technically returns a object[] array instead of a PowerShell collection or PSCustomObject, when the web service call returns a JSON array.
You need to do "something" to the result to force it to convert into a regular PowerShell collection of PSCustomObject data. One thing you can do is simply wrap the call in parentheses, like this:
code:
(Invoke-RestMethod -UseDefaultCredentials  -Uri "$script:UrlBase/api/v1/thingy" -Method GET)
Tada now everything works.

By the way this is on PowerShell 5.1.17763.1007 on Windows 10 1809. Maybe it's fixed/improved in the newer versions.

I'm working on a similar project and can confirm that the behavior is the same for PowerShell 7.0.3 on Windows 10 2004.

Adbot
ADBOT LOVES YOU

mystes
May 31, 2006

nielsm posted:

Fake edit: I found the answer while writing this post, so leaving it here so anyone else can maybe learn too.
The issue is that Invoke-RestMethod technically returns a object[] array instead of a PowerShell collection or PSCustomObject, when the web service call returns a JSON array.
You need to do "something" to the result to force it to convert into a regular PowerShell collection of PSCustomObject data. One thing you can do is simply wrap the call in parentheses, like this:
code:
(Invoke-RestMethod -UseDefaultCredentials  -Uri "$script:UrlBase/api/v1/thingy" -Method GET)
Tada now everything works.
I have to say that confusing coercion of return types is one of the most annoying things about powershell.

mystes fucked around with this message at 14:36 on Aug 7, 2020

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