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
New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Jethro posted:

I had no idea about , and the true meaning of @() until I looked it up the other day, so thank you, New Yorp New Yorp, for giving me a reason to finally learn about one of the parts of Powershell that no one gets right in posted snippets.

The unary operator still doesn't behave "correctly" (for my personal definition of correctly, of course) when piping into ConvertTo-Json. It's definitely good to know, but it's not a solution to the specific scenario I was bitching about.

code:
$foo = @(@{ x = 'xy' })

$foo | convertto-json 
,$foo | ConvertTo-Json
code:
{
    "x":  "xy"
}
{
    "value":  [
                  {
                      "x":  "xy"
                  }
              ],
    "Count":  1
}
The desired output here would be
code:
{
  [
    {
      "x":  "xy"
    }
  ]
}

Adbot
ADBOT LOVES YOU

thebigcow
Jan 3, 2001

Bully!
Maybe Converto-Json is just busted, like how -Whatif is silently ignored on a bunch of AD cmdlets.

Warbird
May 23, 2012

America's Favorite Dumbass

Any of you folks use Chocolatey? I've got an Oracle client that is being an absolute fucker and I'm fairly sure that I'm missing something. We have an response file for the install, but the executable requires a full path to said file. No ./tools/foo.rsp here. I can run the install straight from PS just fine, but once it goes into Chocolatey it breaks all to hell; the exit code is consistent with being unable to find the response file. I've copied the file to C: just to have it in a static place outside of the packaging process, but it still fails during packing install. Anyone have any suggestions on potential next steps to resolve? I'm currently out of ideas.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
Trying to construct a function with some parameter sets, not sure if what I want to do is actually possible. This is a "get" function. By default I want it to get "all" the parameters, but I want to allow using -AllFields:$false to only get "default" values. I ALSO want to, in a separate parameter set, allow a -Fields parameter where the user can specify which fields they want. It wouldn't make sense to pass AllFields and Fields in the same command so I'd like to use Parameter Sets to prevent that... So I wrote this but it doesn't seem very elegant. Checking if AllFields was specified then acting on it, else checking if fields was specified and acting on that, else building the default URL. And using a DefaultParameterSetName that doesn't exit.
code:
function Get-GFilePermissions
{
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    Param
    (
        [Parameter(Mandatory)]
        [string]$accessToken,

        #[Alias("spreadSheetID")]
        [Parameter(Mandatory)]
        [string]$fileID,

        # Parameter help description
        [Parameter(Mandatory,ParameterSetName="All")]
        [switch]$allFields,

        # Parameter help description
        [Parameter(Mandatory,ParameterSetName="Specify")]
        [string]
        $fields
    )

    Begin
    {
        if ($PSBoundParameters.ContainsKey("AllFields")) {
            if ($allFields) {
                $uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/?fields=*"
            } else {
                $uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/"
            }
        } elseif ($PSBoundParameters.ContainsKey("fields")) {
            $uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/?fields=$fields"
        } else {
            $uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/?fields=*"
        }
        $headers = @{"Authorization"="Bearer $accessToken"}
    }

    Process
    {
        Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
    }
    End{}
}
I guess I could also do a switch statement on $PSCmdlet.ParameterSetName but that doesn't change the meat of the problem which is that I'm having to define my "default" twice. I also don't know which is better coding practice, what I've got above or switch on ParameterSetName.

Irritated Goat
Mar 12, 2005

This post is pathetic.
Help me save my own sanity. I’m trying to scrape for a specific device on specific PCs using WMI wrapped in an invoke-command. If I do it manually PC by PC, it works. It’s only when I add in Import-CSV file.csv | does it return nothing.

The CSV is just:
Name
PC1
PC2
PC3

Ideas?

sloshmonger
Mar 21, 2013

FISHMANPET posted:

Trying to construct a function with some parameter sets, not sure if what I want to do is actually possible. This is a "get" function. By default I want it to get "all" the parameters, but I want to allow using -AllFields:$false to only get "default" values. I ALSO want to, in a separate parameter set, allow a -Fields parameter where the user can specify which fields they want. It wouldn't make sense to pass AllFields and Fields in the same command so I'd like to use Parameter Sets to prevent that... So I wrote this but it doesn't seem very elegant. Checking if AllFields was specified then acting on it, else checking if fields was specified and acting on that, else building the default URL. And using a DefaultParameterSetName that doesn't exit.

I guess I could also do a switch statement on $PSCmdlet.ParameterSetName but that doesn't change the meat of the problem which is that I'm having to define my "default" twice. I also don't know which is better coding practice, what I've got above or switch on ParameterSetName.

I abandoned the recent opportunity I had to use them, but I believe the search term you're looking for is Dynamic Parameters or dynamicparam. If you find a good example, please report back. Hopefully that'll set you in the right direction so you don't have to double/triple your effort.

Edit: Ignore this. Mario has it below.

Irritated Goat posted:

Help me save my own sanity. I’m trying to scrape for a specific device on specific PCs using WMI wrapped in an invoke-command. If I do it manually PC by PC, it works. It’s only when I add in Import-CSV file.csv | does it return nothing.

The CSV is just:
Name
PC1
PC2
PC3

Ideas?


Can you tell if it's misbehaving on your computer, or on the remote computer?
Are you passing local variables to the remote computer with the $using:variable?
Credentials being passed successfully?
Do you know at what point in your script/import it's failing?

One thing that helps me troubleshooting a new script is having Write-Host "Some-Command -and $arguements1 -but $argument2 | Do-something -useful" right before whatever the command is, so I can see what the script is running versus what I think it should be running. All of a sudden I'm passing a $null argument? Easy to see.

sloshmonger fucked around with this message at 03:42 on Feb 20, 2019

Mario
Oct 29, 2006
It's-a-me!

FISHMANPET posted:

I guess I could also do a switch statement on $PSCmdlet.ParameterSetName but that doesn't change the meat of the problem which is that I'm having to define my "default" twice. I also don't know which is better coding practice, what I've got above or switch on ParameterSetName.
$allFields is a mandatory switch, so it will never be $false when invoked with the "All" parameter set(e: nope, can be forced to false with -allFields:$false, but it seems awkward to do that. Still you can get this "switch always true" behavior with a validation set). Maybe have a third parameter set "Default"?
code:
    Param (
        [Parameter(Mandatory = $True, ParameterSetName = "All")]
        [ValidateSet($True)]
        [switch]$AllFields
        ,
        [Parameter(Mandatory = $True, ParameterSetName = "Default")]
        [ValidateSet($True)]
        [switch]$DefaultFields
        ,
        [Parameter(Mandatory = $True, ParameterSetName = "Specify")]
        [string]$FieldList
        ,
        [Parameter(Mandatory = $True)]
        [string]$AccessToken
    )
    
    if ($AllFields)
    {
        
    }
    elseif ($DefaultFields)
    {
        
    }
    else
    {
        # Use FieldList
    }

Mario fucked around with this message at 03:08 on Feb 20, 2019

mllaneza
Apr 28, 2007

Veteran, Bermuda Triangle Expeditionary Force, 1993-1952




Irritated Goat posted:

Help me save my own sanity. I’m trying to scrape for a specific device on specific PCs using WMI wrapped in an invoke-command. If I do it manually PC by PC, it works. It’s only when I add in Import-CSV file.csv | does it return nothing.

The CSV is just:
Name
PC1
PC2
PC3

Ideas?

Is that a scope issue ? Yeah, that's probably scope. At a guess, you're probably importing the CSV in one function and trying to do something with the contents in another.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams

Mario posted:

$allFields is a mandatory switch, so it will never be $false when invoked with the "All" parameter set(e: nope, can be forced to false with -allFields:$false, but it seems awkward to do that. Still you can get this "switch always true" behavior with a validation set). Maybe have a third parameter set "Default"?

Maybe I'm not quite understanding, because if you set the ValidateSet to only $True then you can't do -param:$false. Now granted, setting switches to true by default is apparently against best practice so I guess it's kind of weird that I'm asking "what's the best way to follow best practices when I'm violating best practices."

The reason I'm doing this is my team has a publicly available Powershell Module to interact with data from Google Sheets: https://github.com/umn-microsoft-automation/UMN-Google but I'm sure very few, if any, people are using it. And the module I'm working on, Get-GFilePermissions, is currently so useless that even if you're using the module, you're probably not using that function. But it's there, and it does something and so it's possible that someone is using it. So I'm changing the function to be slightly smarter, and debating how much I want to preserve the current format of the data that it returns vs improving it to be actually useful (but making it easy for someone to fix their code if they want to keep using it the old dumb way?).

I'm most assuredly thinking way too hard about this dumb cmdlet because I could make it work and make it pull all the data by adding 9 characters but damnit I wanna do it right!

Irritated Goat
Mar 12, 2005

This post is pathetic.

mllaneza posted:

Is that a scope issue ? Yeah, that's probably scope. At a guess, you're probably importing the CSV in one function and trying to do something with the contents in another.

Now that I'm at a PC, the code I'm using is:

code:
Invoke-Command -ComputerName XXXXX {gwmi Win32_PnPSignedDriver | select devicename,driverversion | Select-Object DeviceName | Select-String 'Canon'}
I get the response I want out of that.

If I do
code:
Import-CSV C:\Temp\PCs.csv | ForEach-Object {Invoke-Command -ComputerName $._Name {gwmi Win32_PnPSignedDriver | select devicename,driverversion | Select-Object DeviceName | Select-String 'Canon'}}
I get nothing in response.

The Fool
Oct 16, 2003


Not sure if typo, but it should be

code:
$_.Name
not
code:
$._Name

Irritated Goat
Mar 12, 2005

This post is pathetic.

The Fool posted:

Not sure if typo, but it should be

code:
$_.Name
not
code:
$._Name

Typo. I always get those swapped till Powershell yells at me.

Submarine Sandpaper
May 27, 2007


FISHMANPET posted:

Maybe I'm not quite understanding, because if you set the ValidateSet to only $True then you can't do -param:$false. Now granted, setting switches to true by default is apparently against best practice so I guess it's kind of weird that I'm asking "what's the best way to follow best practices when I'm violating best practices."

The reason I'm doing this is my team has a publicly available Powershell Module to interact with data from Google Sheets: https://github.com/umn-microsoft-automation/UMN-Google but I'm sure very few, if any, people are using it. And the module I'm working on, Get-GFilePermissions, is currently so useless that even if you're using the module, you're probably not using that function. But it's there, and it does something and so it's possible that someone is using it. So I'm changing the function to be slightly smarter, and debating how much I want to preserve the current format of the data that it returns vs improving it to be actually useful (but making it easy for someone to fix their code if they want to keep using it the old dumb way?).

I'm most assuredly thinking way too hard about this dumb cmdlet because I could make it work and make it pull all the data by adding 9 characters but damnit I wanna do it right!
Use a switch. Will never hit default though with the param as mandatory.

code:
function Get-GFilePermissions
{
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    Param
    (
        [Parameter(Mandatory)]
        [string]$accessToken,

        #[Alias("spreadSheetID")]
        [Parameter(Mandatory)]
        [string]$fileID,

        # Parameter help description
        [Parameter(Mandatory,ParameterSetName="All")]
        [switch]$allFields,

        # Parameter help description
        [Parameter(Mandatory,ParameterSetName="Specify")]
        [string]$fields
    )

    Switch ($PSBoundParameters.keys)
    {
        allfields {$uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/?fields=*" 
            break}
        fields {$uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/?fields=$fields" 
            break}
        default {$uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions/"}
    }
    $headers = @{"Authorization"="Bearer $accessToken"}
    Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
}
/e - actually it will always hit default without the break due to the other mandatory params, maybe add a third in your setname or just dump mandatory? Heck you could also invoke-restmethod in the switch.

Submarine Sandpaper fucked around with this message at 20:46 on Feb 20, 2019

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
I decided I was probably overthinking this, and also not really keeping in line with the philosophy of the rest of the modules, so I went with this. Generally speaking, with the rest of the cmdlets, we'll grab everything and return it to you and let you filter it locally rather than trying to construct a REST call to get only what you specify. So if you only want some of the fields, just get them all and select-object those properties.
By default it will append /?fields=* to the URI, unless you specify -Default fields in which case it will leave that out. It also lets you specify a PermissionID which gets you one specific permission object rather than all permissions for a file.
code:
function Get-GFilePermissions
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [string]$accessToken,

        #[Alias("spreadSheetID")]
        [Parameter(Mandatory)]
        [string]$fileID,

        # Parameter help description
        [Parameter()]
        [string]
        $permissionID,

        # Parameter help description
        [Parameter()]
        [switch]
        $DefaultFields
    )

    Begin
    {
        $uri = "https://www.googleapis.com/drive/v3/files/$fileID/permissions"
        if ($permissionID) {
            $uri += "/$permissionID"
        }
        if (-not $DefaultFields) {
            $uri += "/?fields=*"
        }
        $headers = @{"Authorization"="Bearer $accessToken"}
    }

    Process
    {
        Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
    }
    End{}
}

The Fool
Oct 16, 2003


Irritated Goat posted:

Now that I'm at a PC, the code I'm using is:

code:
Invoke-Command -ComputerName XXXXX {gwmi Win32_PnPSignedDriver | select devicename,driverversion | Select-Object DeviceName | Select-String 'Canon'}
I get the response I want out of that.

If I do
code:
Import-CSV C:\Temp\PCs.csv | ForEach-Object {Invoke-Command -ComputerName $._Name {gwmi Win32_PnPSignedDriver | select devicename,driverversion | Select-Object DeviceName | Select-String 'Canon'}}
I get nothing in response.

Stop doubling up on Select-Object and use Where-Object instead of Select-String.

Something like
code:
Where-Object { $_.DeviceName -like "Canon*"}

Mario
Oct 29, 2006
It's-a-me!

FISHMANPET posted:

Maybe I'm not quite understanding, because if you set the ValidateSet to only $True then you can't do -param:$false. Now granted, setting switches to true by default is apparently against best practice so I guess it's kind of weird that I'm asking "what's the best way to follow best practices when I'm violating best practices."
I could definitely be using switch parameters "wrong" there, with the idea that you'd never want to set any of them to $false and just have three parameter sets for the three modes (all fields, default fields, specific fields). Looks like you've arrived at something even simpler in the end.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
Yeah there's some vmware cmdlets that have -confirm be true by default, and to override that you need to specify -confirm:$false and so I thought I'd be clever and do that, but according to PSScriptAnalyzer setting switches to true by default is bad practice so I decided to stop overthinking it.

ThatNateGuy
Oct 15, 2004

"Is that right?"
Slippery Tilde
Have any of you guys played around with PowerShell Core (6) on Linux or Mac OS X? How was it? Bonus points if you've also used it with OMI. I don't want to bash Bash (ehhhh) but I like the structured data that PowerShell offers a lot more than the pure text of UNIX-based systems. if I can manage a system just as well with pwsh, I don't see why I shouldn't.

Pile Of Garbage
May 28, 2007



FISHMANPET posted:

Yeah there's some vmware cmdlets that have -confirm be true by default, and to override that you need to specify -confirm:$false and so I thought I'd be clever and do that, but according to PSScriptAnalyzer setting switches to true by default is bad practice so I decided to stop overthinking it.

Did it complain about setting switch arguments in general or about specifically setting Confirm switch arguments? The former doesn't make sense but the latter kind of does given how the Confirm argument is built-in and exposed when SupportsShouldProcess is enabled. This page provides a better run-down of how it works: https://docs.microsoft.com/en-us/powershell/developer/cmdlet/requesting-confirmation-from-cmdlets#supporting-confirmation-requests.

From what I understand if you're wrapping cmdlets which support should-process then you you should be setting the $ConfirmPreference variable appropriately so that it can be read by the wrapped cmdlet.

Edit: to maybe clarify, the intention is that things like confirmation and what-if should be passed-through from the wrapping script/method.

ThatNateGuy posted:

Have any of you guys played around with PowerShell Core (6) on Linux or Mac OS X? How was it? Bonus points if you've also used it with OMI. I don't want to bash Bash (ehhhh) but I like the structured data that PowerShell offers a lot more than the pure text of UNIX-based systems. if I can manage a system just as well with pwsh, I don't see why I shouldn't.

I haven't tried PowerShell Core but I do have a deep dislike of Bash scripting due to its exceptionally obtuse syntax. I guess the usefulness of PowerShell Core will depend on how much of .NET has been ported across to .NET Core.

thebigcow
Jan 3, 2001

Bully!
I had to fix a module that called a library because it was all lower case in the psm1 file but mixed case in the actual file name and that actually matters on Linux.

I was *this* close to actually making a github account so I could ask them to fix it.

CzarChasm
Mar 14, 2009

I don't like it when you're watching me eat.
I'm having a problem with trying to get a split or another way to break up a string to work. Overall, what I'm trying to do is go to my (GMAIL) mailbox and run a report on all the messages that are in there, including the file names of attachments. Here's what I have.
code:
if ($msg2.attachments -NE "") { # If the message has an attachment 
        $ContentType = $msg2.Headers.'Content-Type' #Grab the value in Content-Type from the Header
        $Parts = $ContentType.split("=")        #Split the value based on where "=" appears in the string
        $attachNames = $Parts[1]}   #Grab the right half of the string where the split happens
Note: msg2.attachments does not have a "Name" or other ID value, it basically just shows the value "AE.Net.Mail.Attachment" for any attachment. Basically just a "Yup, this email has an attachment"

Unfortunately, the split method doesn't work on $ContentType - according to powershell, it does not contain that method. I also tried using a substring method, but that is also not present.

I have tried converting the variable to string by using [string]$ContentType, but that didn't really do anything

As an example, this is what $ContentType contains if there is an attachment:
Content-Type: application/octet-stream; name=lead_attachment.xml

I have a second issue where there could be multiple instances of Content-Type in the header, but if I can't get it to pull the string data anyway there's not much point in getting it to narrow down the right value.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
$ContentType.GetType() will tell you what that object actually is. If you just "call" the variable in your shell or use write-host to print it to the console it will convert it to a string to display, but that error means it's probably not a string. It should have a .ToString() method if you really want to do string manipulation on it but you may be able to do more with the original object in its native type.

You can also pipe it into Get-Member ($ContentType | Get-Member) and it will show you type type as well as all properties and methods of the object.

CzarChasm
Mar 14, 2009

I don't like it when you're watching me eat.
I tried the GetType and it turns out this is a System.ValueType and if I do a .Value, it returns that it is multipart/mixed. Which I guess explains part of the problem.

So, I can type $ContentType.Value(), so how would I go about selecting just the second or third part of this multipart record?

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
Hard to say without having an object of that type to play around with in the console, but everything is an object, so if it's got a Value property, you can do "$ContentType.Value | get-member" and see what's there. And so on and so on, it's objects all the way down.

Also you wouldn't use () after Values, because Values is a property not a method. So GetType() is a method so it needs the parenthesis (because methods can potentially take parameters) but properties don't take parameters so you'd get a failure if you tried Values().

sloshmonger
Mar 21, 2013

CzarChasm posted:

I'm having a problem with trying to get a split or another way to break up a string to work. Overall, what I'm trying to do is go to my (GMAIL) mailbox and run a report on all the messages that are in there, including the file names of attachments. Here's what I have.
code:
if ($msg2.attachments -NE "") { # If the message has an attachment 
        $ContentType = $msg2.Headers.'Content-Type' #Grab the value in Content-Type from the Header
        $Parts = $ContentType.split("=")        #Split the value based on where "=" appears in the string
        $attachNames = $Parts[1]}   #Grab the right half of the string where the split happens
Note: msg2.attachments does not have a "Name" or other ID value, it basically just shows the value "AE.Net.Mail.Attachment" for any attachment. Basically just a "Yup, this email has an attachment"

Unfortunately, the split method doesn't work on $ContentType - according to powershell, it does not contain that method. I also tried using a substring method, but that is also not present.

I have tried converting the variable to string by using [string]$ContentType, but that didn't really do anything

As an example, this is what $ContentType contains if there is an attachment:
Content-Type: application/octet-stream; name=lead_attachment.xml

I have a second issue where there could be multiple instances of Content-Type in the header, but if I can't get it to pull the string data anyway there's not much point in getting it to narrow down the right value.

You may be able to use the PowerShell -split operation rather than the .NET .split() method
code:
$Parts = $ContentType -split "="
I have a feeling you're going to need to stop worrying and love the regex.

CzarChasm
Mar 14, 2009

I don't like it when you're watching me eat.
Thanks for the help, the -split managed to get me what's in the field in a way I can use it.

PierreTheMime
Dec 9, 2004

Hero of hormagaunts everywhere!
Buglord
Finally updated to 5.1 and immediately got to use a class, which is super handy. Not that custom objects didn't work before, but this format is familiar and reads better.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
Ok, so I'm trying to write up a tool we can use in our lab to quickly grab important info from the lab machines and display it in a way that our non-technical techs can handle. I'm not 100% on how the UI stuff works, though. I've got a working form, and it populates great, but when I moved the form population from the end of the scan to updating after each machine, it basically locks me out of the form until the scan completes. I can still see it populating, but the form won't respond to any inputs (I have to close the underlying powershell window to kill it).

https://pastebin.com/h2nb50W9

Pile Of Garbage
May 28, 2007



Toshimo posted:

Ok, so I'm trying to write up a tool we can use in our lab to quickly grab important info from the lab machines and display it in a way that our non-technical techs can handle. I'm not 100% on how the UI stuff works, though. I've got a working form, and it populates great, but when I moved the form population from the end of the scan to updating after each machine, it basically locks me out of the form until the scan completes. I can still see it populating, but the form won't respond to any inputs (I have to close the underlying powershell window to kill it).

https://pastebin.com/h2nb50W9

PowerShell isn't meant to do UIs, it's a console scripting language which performs best in situations with as little interaction as possible. In fact in its truest form PowerShell is meant to run without interaction whilst doing the heavy-lifting for things related to automation, orchestration and reporting. The only reason that it can do UIs altogether is because it can leverage the entire .NET Framework which happens to include classes for creating UIs.

Maybe it'd be easier to just have PowerShell output the data you require into a location where it can be consumed by a real front-end application.

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal
That's exactly why we're lifting our json data into postgres. Powershell is good at consuming and writing json to ingest, transform, and act on data, but it's really not good at displaying it anywhere other than custom powershell views in the console.

I have been known to do an out-gridview here and there in a pinch but it's not my favorite.

mystes
May 31, 2006

Toshimo posted:

Ok, so I'm trying to write up a tool we can use in our lab to quickly grab important info from the lab machines and display it in a way that our non-technical techs can handle. I'm not 100% on how the UI stuff works, though. I've got a working form, and it populates great, but when I moved the form population from the end of the scan to updating after each machine, it basically locks me out of the form until the scan completes. I can still see it populating, but the form won't respond to any inputs (I have to close the underlying powershell window to kill it).

https://pastebin.com/h2nb50W9
You need to run ShowDialog in a separate thread using Start-Job or something but it's kind of annoying in powershell.

It's usually easier to just use c# once you're doing gui stuff.

Warbird
May 23, 2012

America's Favorite Dumbass

Is there a simple way to install a standalone version of the SQL Server Module that I'm missing? MS docs say you have to download it from their servers via Install-Module, but all that's blocked on our network. We've attempted extracting the module from a SQL full install and manually doing it, but it becomes a nightmare of needing random .dlls and other files.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
You should figure out how to get that unblocked, it's like saying "work blocks Ubuntu update servers how do I apt-get install anything"

Warbird
May 23, 2012

America's Favorite Dumbass

They also block Github and Chocolatey. I was explicitly hired to work on the latter and have to use a personal laptop/wayback machine to reference docs. So not gonna happen.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

mystes posted:

You need to run ShowDialog in a separate thread using Start-Job or something but it's kind of annoying in powershell.

It's usually easier to just use c# once you're doing gui stuff.

Thanks, I'll give it a shot. I don't really have the excess time and bandwidth to develop apps in another language, so I'm kinda at the point where if I can't make something work with the tools I've got, I'm just gonna not bother.

Zaepho
Oct 31, 2013

Warbird posted:

They also block Github and Chocolatey. I was explicitly hired to work on the latter and have to use a personal laptop/wayback machine to reference docs. So not gonna happen.

From said other machine Save-Module then copy it over.

Warbird
May 23, 2012

America's Favorite Dumbass

That appears to be the way to go, but you're then running into some dependencies on having NuGet installed and some other weirdness. I'll keep playing with it, but I suspect we're just going to use a 2017 full MySql install with just the tools and then doing the standalone SSRS install before running the post install config steps.

mystes
May 31, 2006

Toshimo posted:

Thanks, I'll give it a shot. I don't really have the excess time and bandwidth to develop apps in another language, so I'm kinda at the point where if I can't make something work with the tools I've got, I'm just gonna not bother.
Actually looking at your code you can try something like this within the function that is called when the button is clicked. If you run the slow stuff in a separate runspace then you can use Control.BeginInvoke to update the form in the gui thread. This example is just if you have a label $label and are incrementing it every second but you should be able to adapt it to your code; also you should probably close the runspace if your form is closed. You may be able to get it to work with jobs also (which might be simpler) but I couldn't get it to work just now and I didn't feel like trying to figure it out.
code:
$Runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($Host)
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable('label', $label)
$PowerShellRunspace = [Management.Automation.PowerShell]::Create()
$PowerShellRunspace.Runspace = $Runspace
$PowerShellRunspace.AddScript(
     {
    $updatelabel = [Action[Object]] {
        Param($i)
        $label.Text = $i.toString()
    }

    foreach ($i in 1..10) {
        Start-Sleep -Seconds 1
        write-host $i
        $label.BeginInvoke($updatelabel,$i)
        }
     })

$PowerShellRunspace.BeginInvoke() | Out-Null
Again, you are making this harder by insisting on using powershell though.

mystes fucked around with this message at 20:11 on Mar 22, 2019

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams

Warbird posted:

They also block Github and Chocolatey. I was explicitly hired to work on the latter and have to use a personal laptop/wayback machine to reference docs. So not gonna happen.

To be clear that's the stupidest loving thing in the world and if I were you I'd be looking for another job if they've hired you to do something explicitly and then explicitly prevented you from doing that thing. Because yeah as you've figured out there's no good way to reinvent packaging.

Adbot
ADBOT LOVES YOU

Warbird
May 23, 2012

America's Favorite Dumbass

Oh believe me I'm either out of here or increasing my rate by a nice chunk when this contract is up in a few months.

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