Is there something like an intro or a short manual for Powershell targeted at those who know lots of Unix shell scripting?



  • Just wondering if there's something of a good intro for those who don't need to have shell scripting explained to them as a concept, who don't come from command.com/cmd.exe world, but who also don't give too much shit about .NET/C# (I know Powershell maps many concepts from there straight so C#-ers can feel at home). Most information online targets these audiences.

    The reason I'm asking is that my possible project in a week's time involves having to work on Windows 7. What I need is a means to reduce grunt work and eventually share these scripts with teammates, without having them install Python, or MSYS, or anything like that.

    Also, I want to be efficient on this not particularly developer-friendly platform, if that's even possible.

    Another reason why I'm asking there, in addition to just fucking googling it, is that there's a chance someone actually read something and can make an educated recommendation. So far Google turns up very little useful results. :frowning:



  • Not quite sure about a specific tutorial (I'd like one too) but I know a design decision Microsoft made during Powershell's development was to make it easy for people coming from (ba)sh scripting to use, hence the aliases ls->dir, etc. So hopefully it will be pretty easy for you to get the hang of.



  • I don't know if this is useful to you or not... but Powershell has an IDE. Well, they call it an ISE, but same thing.

    It's called Windows Powershell ISE and it should be installed if Powershell is.



  • First thing I had to find out about Powershell scripts was how to make the fucking things actually run when you double-click them.


  • sockdevs

    @flabdablet said:

    First thing I had to find out about Powershell scripts was how to make the fucking things actually run when you double-click them.

    I learned well

    $> Set-ExecutionPolicy Bypass
    $> iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
    

    okay, maybe not the most secure in the world but windows is a bit paranoid about running powershell scripts.... (and probably not unjustifiably)



  • @wft said:

    Just wondering if there's something of a good intro for those who don't need to have shell scripting explained to them as a concept, who don't come from command.com/cmd.exe world

    The official intro is pretty good if you only want to see the syntax.

    @wft said:

    Also, I want to be efficient on this not particularly developer-friendly platform, if that's even possible

    I have to disagree with this. If you're a developer, PowerShell can do more than just glue together commands and provide flow control. The ability to use the entire .Net Framework gives developers a huge library of code to leverage. I often find myself doing a mental C#-to-PowerShell conversion before even realizing that there is already an applet that does what I want to do.



  • @Jaime said:

    appletcmdlet

    FTFY. :wtf:, this isn't Java.



  • @rc4 said:

    @Jaime said:
    appletcmdlet

    FTFY. :wtf:, this isn't Java.

    The term "applet" was in use before Java stole it. For example, Windows Control Panel items have been called applets since at least Windows 3.0's release in 1990.

    ...but yes, since it's command line, cmdlet is probably more accurate.



  • I'm aware, however, Powershell doesn't call the things he was referring to "applets," it calls them "cmdlets." Similar to Jaime calling what is really a banana an apple, me correcting him, and then you saying "well, they're both fruit and bananas have been around longer!"



  • @rc4 said:

    I'm aware, however, Powershell doesn't call the things he was referring to "applets," it calls them "cmdlets." Similar to Jaime calling what is really a banana an apple, me correcting him, and then you saying "well, they're both fruit and bananas have been around longer!"

    It's almost like you didn't read my second paragraph while creating that metaphor.

    Also, here's something for free for automatically associating applets with Java:



  • The first thing you'll have to learn: you are not passing around strings like in bash, you are passing around objects instead. And that makes for some pretty cool features.

    For example, take the following snippet:

    $items = ls | where { $_.Name.Contains("S"); }     # Takes all items in the current folder whose name contains the letter S 
    $sorted = $items | sort LastWriteTime -Descending  # Do some fancy sorting
    $sorted |  ConvertTo-Csv -NoTypeInformation | Out-File test.csv
    

    This takes all items in a folder where the name contains a letter S, sorts it by LastWriteTime, and then dumps it into a CSV file.



  • I preferred "Desk Accessory".



  • Wait, so Microsoft made this "really awesome guys" scripting platform, then disabled it by default on all their systems just in case?

    :wtf: :wtf: :wtf:



  • No, they put a trivial barrier in front of executing scripts so the unaware wouldn't be tricked into running a malicious script.



  • This was an appallingly ill-considered move. As you point out, the barrier is trivial; if I want to make a clickable script that works on any Windows box by default, all I have to do to work around it is package up my Powershell scripts in a cmd wrapper.

    The default Restricted execution policy does nothing to protect end users from malware; its only effect is to irritate script authors. It's the software equivalent of the TSA.



  • @flabdablet said:

    It's the software equivalent of the TSA.

    Not quite, because the TSA gives people an illusion of safety, whereas the only people who would ever know about the non-usable-by-default Powershell stuff are the ones who actually want to run the scripts.

    It would be more like the TSA being posted at a military hardware manufacturer's shipping dock and then taking everything that the company produced and confiscating it.



  • Mmmkay. Does Powershell provide any introspection tools without me having to go to C# docs and then "translate"? You know, like dir() and help() in Python.



  • @AlexMedia said:

    $items = ls | where { $_.Name.Contains("S"); }

    This is some of the insanest shell-perl-java mixtures I've ever seen!



  • Try the Get-Help cmdlet. This gives you all the information about a cmdlet that you might possibly need.

    PS C:\> get-help ls
    
    NAME
        Get-ChildItem
    
    SYNOPSIS
        Gets the items and child items in one or more specified locations.
    
    
    SYNTAX
        Get-ChildItem [[-Path] <string[]>] [[-Filter] <string>] [-Exclude <string[]>] [-Force] [-Include <string[]>] [-Name] [-Recurse] [-UseTransaction] [<CommonParameters>]
    
        Get-ChildItem [-LiteralPath] <string[]> [[-Filter] <string>] [-Exclude <string[]>] [-Force] [-Include <string[]>] [-Name] [-Recurse] [-UseTransaction] [<CommonParameters>]
    
    
    DESCRIPTION
        The Get-ChildItem cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers.
    
        A location can be a file system location, such as a directory, or a location exposed by another provider, such as a registry hive or a certificate store.
    
    
    RELATED LINKS
        Online version: http://go.microsoft.com/fwlink/?LinkID=113308
        about_Providers
        Get-Item
        Get-Alias
        Get-Location
        Get-Process
    
    REMARKS
        To see the examples, type: "get-help Get-ChildItem -examples".
        For more information, type: "get-help Get-ChildItem -detailed".
        For technical information, type: "get-help Get-ChildItem -full".


  • And what about objects a command returns? How do I poke around their properties and methods inside shell?



  • If you do Get-Help ls -Full the help includes information about the type of the returned object. For ls however, this is Object because it depends on the provider - the file system returns different types than the registry.

    After you've done something like:
    $x = Get-Item C:\Windows\WindowsUpdate.log

    You can do tab completion when typing $x. This will enumerate through all the properties of an object. You can also tabcomplete on cmdlets and parameters.



  • @AlexMedia said:

    You can do tab completion when typing $x. This will enumerate through all the properties of an object.

    See them as a list? (Windows tab autocompletion one-at-a-time is the most utterly moronic thing one could come up when making autocompletes) See documentation on them right from REPL?


  • Discourse touched me in a no-no place

    @powerlord said:

    That turn just wants to run freeeee....



  • You can use Get-Member to print the methods and properties of a type (slightly old example, current documentation). I don't know if there's a way to see .NET documentation in PowerShell itself.



  • Well, I just want to see what a certain property really is. Having to do it with a browser with the whole of fucking MSDN kinda defeats the purpose, and also, MSDN may be documenting things that differ from those on my system.

    Python has this wonderful system of docstrings for everything, Java has JavaDoc, SQL has COMMENT ON ANYTHING, and here...?

    (Also, I can't get over an impression PS syntax is verbose as hell, but if they can autocomplete their -LongParameterNames, it might be okay.)



  • PowerShell Community Extensions extends Get-Help to support reading local .NET documentation or opening MSDN, but it's a bit clunky to use (and also opens MSDN in Internet Explorer rather than the default browser). You have to explicitly enable the help module with Import-Module Pscx -arg @{ModulesToImport = @{GetHelp = $true}}.

    The documentation of the help module doesn't seem to visible in PowerShell itself, but there is a help comment in the module file itself (C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Modules\GetHelp\Pscx.GetHelp.psm1).

    Basically, use Get-Help -obj $someObject or Get-Help -obj [SomeType] to get help for the type and Get-Help -Object $someObject.SomeMethod to get help for the method. Fields and properties aren't supported. Use the -online argument to go directly to the MSDN page, skipping the local help.



  • Is that case-sensitive?

    I mean, Get-Help. Really. One's gotta love the shift key.



  • I doubt most people type Get-Help, considering it's aliased to man.



  • No, PowerShell is case-insensitive so the case of cmdlet/function names and switches doesn't matter. get-HELP -oBJect 1, gEt-help -object 1 and get-help -OBJECT 1 are all valid.

    .NET methods with string arguments usually treat them as case-sensitive, so ("a","b","c").Contains("A") (.NET method) returns false, but ("a","b","c") -contains "A" (PowerShell operator) returns true.



  • Well, thanks!



  • I'll bet that doesn't get confusing!



  • Not really since if you're using .NET methods in a PS script, you KNOW that you're using .NET methods in a PS script.



  • I think there's no much confusion: there are Powershell entities which are not case-sensitive (cmdlets, syntactic sugar), and there are .NET entities which are case-sensitive. It could possibly be a WTF but I think of .NET entities as foreign and bridged into the shell, so I'd have no major problems with that.

    The problem is rather that using more advanced features of PS looks very verbose and there's a lot of boilerplate that has to be copied straight from MSDN, or else it's not gonna work. Well, Unix shells are notorious for punishing you with string escaping bugs unless you are a level 80 shell wizard, and PS gives you a need to write lots of mumbojumbo where sane people would write "import foo" (even in Java!). Look at this gem:

    Import-Module Pscx -arg @{ModulesToImport = @{GetHelp = $true}}

    In Perl, I would just

    use Pscx 'GetHelp';

    (Larry Wall would be proud over PS's gratuitous (ab)use of @{}, and an enterprise programmer would be even happier about the gratuitous use of hashmaps where a list would suffice.)

    Other WTFs: MySQL's MyISAM engine (dunno about InnoDB with "file per table") made tables' case sensitivity dependent on case sensitivity of the underlying filesystem. PHP's keywords, classes, and variables are case-sensitive, while functions are not. I managed to put up with this kind of shit for years, I think I grew a bit of thick skin.



  • Can I invoke cmdlets using C# syntax for more consistency? AFAIU cmdlets themselves are .NET classes/methods of sorts.



  • Cmdlets are .NET classes, so you can instantiate a cmdlet class with New-Object, set the argument properties and then call the Invoke method on it. It's not quite as simple as using PowerShell's cmdlet invocation syntax.

    I don't think PowerShell directly provides the name of a cmdlet's class, but (Get-Command Some-Cmdlet).ModuleName will tell you its namespace and you can usually derive the class name from the cmdlet name (Get-Help is GetHelpCommand).

    Both of the following code blocks produce the same output:

    # .NET style
    $getDate = New-Object Microsoft.PowerShell.Commands.GetDateCommand # Instantiate the Get-Date cmdlet
    $getDate.Date = [DateTime]::Now - (New-Object timespan -ArgumentList @(1,0,0)) # Set the Date argument to (Now - 1 hour)
    $getDate.Invoke() # Invoke it
    
    # PowerShell style
    Get-Date -Date ([DateTime]::Now - (New-Object timespan -ArgumentList @(1,0,0)))
    

    This is a bit like calling a method via reflection instead of the standard method call operator in C#: it's possible, but it's fairly complicated and probably not worth doing unless you have a good reason.

    Most of my PowerShell advice in this thread has been derived from searching the Internet, reading the documentation and experimenting; I don't use it that often myself.

    Edit: PowerShell syntax highlighting doesn't seem to work.



  • Does PS do translation of methods from CapsStyle to -dashed-parameter-style all by itself or are they exported in a dictionary?



  • Class, method, field and property names are case-insensitive (so dofoo, DoFoo and dofOO are all valid), but you can't use dashes in them. Dashes are only valid in command (function/cmdlet/alias/program) names.



  • Nononono. There are different styles of method invocations in PS, one C#-style, and another PS-style (-like-this), see above for a few examples. Is there 1:1 mapping, or do only selected classes have dual-style invocation?



  • Are you sure you're talking about method invocation? Could you post an example of what you mean?

    Argument names are prefixed with a dash when invoking a cmdlet, but they can't have dashes in their names.



  • Ah, I've seen the comparison of .NET methods and PS operators, and for some reason thought about some magic aliasing taking place.



  • @wft said:

    or do only selected classes have dual-style invocation?

    A cmdlet class can only be invoked with the cmdlet syntax if it has the appropriate attribute decorations on it. PowerShell doesn't mangle the method name, it searches for a method with the correct attribute on it.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.