Get Current Drive Letter Using Powershell - powershell

All I'm looking for is a way to get the current drive letter that I am currently running the powershell script from.
I know I can get the current path using Get-Location but is there a way to extract the drive letter without doing some kind of substring operation?

Yes, you can get the drive letter without string operations:
(get-location).Drive.Name
Remember, that PowerShell seldom returns strings, but rich objects. You can always examine your further options from a result by using get-member.
Also note, that if you are not on the file system provider, the Name might not be a one-character string.
Edit:
As per x0n's comment below, here is a shorthand version:
$pwd.drive.name

Related

Powershell: dealing with / in Registry property names

Given this (real) Registry path...
HKEY_CLASSES_ROOT\Local Settings\MrtCache\C:%5CProgram Files%5CWindowsApps%5C89006A2E.AutodeskSketchBook_1.6.0.0_x64__tf1gferkr813w%5Cresources.pri\1d3438f5876f755\6dfb7f2f\#{89006A2E.AutodeskSketchBook_1.6.0.0_x64__tf1gferkr813w?ms-resource://89006A2E.AutodeskSketchBook/Files/Assets/AppLogo/Orion_Tiny.png}
where the property name is...
#{Microsoft.Office.OneNote_17.8625.20901.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.Office.OneNote/Files/images/OneNoteAppList.png}
I am trying to figure out how to properly deal with extracting the data value. I need to differentiate the path to the containing key from the property name, but because the property name contains / and Split-Path converts those to \ and treats them as key delimiters, I get bad data out of that Cmdlet. From a programming standpoint the solution is to not start with a single path. However, I am somewhat constrained by existing data in XML files that provides only a single path. For 99.9% of cases, including drive and UNC file & folder paths, registry Key & Property paths as well as URL paths, Split-Path works. But for this very specific situation it fails. Is there a .NET solution that can be depended on? Or is this a case where there is no solution other than to break up the data and curse Microsoft for their inconsistency and incomplete solutions?
I get that this example is probably a situation I will never actually run into, but I have been burned before with things like assuming anything with an extension is a file and then finding someone (usually Autodesk) has decided to name a bunch of folders with a . in the name, causing code with that assumption about naming conventions to fail. So I am looking for a consistent way to deal with this, if one exists. Ideally in PS 5.1, not PS Core, as I cannot and will not demand that all my users upgrade to a new version of PowerShell to address such an edge case.
EDIT: I should also mention that a similar issue arrises when there is a / in a key name, and I want to verify that the key exists. HKLM\Software\Key/Name is a perfectly valid path, and Split-Path will soil itself every time and come back with Name as the leaf, not Key/Name. Because Split-Path doesn't actually understand what's valid as a registry key name, it seems.

How to use wildcards in nant xmlpoke file path

I am using the xmlpoke task in nant and am looking for a way to use a wildcard when addressing the xml file. Right now I have a file path like project\appFiles\project{versionNumber}\fileToUpdate.xml, I would like to use a wildcard so its something like project\appFiles\project*\fileToUpdate.xml so I don't have to update the version number every time.
How do you get it to respect wildcards?
Looking all over the web, it doesn't look like this is possible, and by design. Like copy command (todir), the file path must point to a single file so no wildcards allowed (Found info on copy command, assuming same applies for XMLPoke, but could confirm exactly).
I ended up changing some design stuff so now the version number is easily calculated by the program calling the script, so passing in not an issue anymore.

how to find operating system label using command line

like we have %windir% which returns the C;\windows , do we have any command that returns only the operating system drive letter ('C') ?
I tried the command "label" but it returns more than the label info..
WMIC.exe allows you to make WMI queries from the command line.
wmic os get systemdrive
will tell you the same thing as %SystemDrive%, though you can also use it for InstallDate, SystemDirectory (i.e. %WINDIR%\System32, though I don't recall ever having seen a machine with a different name for that directory), LastBootupTime, etc.
The output isn't necessarily easy to parse from a script, but if you just want to see the info, it's very useful.
On windows, try these:
1. %SystemDrive%
2. %HOMEDRIVE%
The first gives you the drive letter that holds your system files, the second gives you drive letter that holds your documents.

zip recursively each file in a dir, where the name of the file has spaces in it

I am quite stuck; I need to compress the content of a folder, where I have multiple files (extension .dat). I went for shell scripting.
So far I told myself that is not that hard: I just need to recursively read the content of the dir, get the name of the file and zip it, using the name of the file itself.
This is what I wrote:
for i in *.dat; do zip $i".zip" $i; done
Now when I try it I get a weird behavior: each file is called like "12/23/2012 data102 test1.dat"; and when I run this sequence of commands; I see that zip instead of recognizing the whole file name, see each part of the string as single entity, causing the whole operation to fail.
I told myself that I was doing something wrong, and that the i variable was wrong; so I have replaced echo, instead than the zip command (to see which one was the output of the i variable); and the $i output is the full name of the file, not part of it.
I am totally clueless at this point about what is going on...if the variable i is read by zip it reads each single piece of the string, instead of the whole thing, while if I use echo to see the content of that variable it gets the correct output.
Do I have to pass the value of the filename to zip in a different way? Since it is the content of a variable passed as parameter I was assuming that it won't matter if the string is one or has spaces in it, and I can't find in the man page the answer (if there is any in there).
Anyone knows why do I get this behavior and how to fix it? Thanks!
You need to quote anything with spaces in it.
zip "$i.zip" "$i"
Generally speaking, any variable interpolation should have double quotes unless you specifically require the shell to split it into multiple tokens. The internal field separator $IFS defaults to space and tab, but you can change it to make the shell do word splitting on arbitrary separators. See any decent beginners' shell tutorial for a detailed account of the shell's quoting mechanisms.

Run a PowerShell script from another one

What is the best and correct way to run a PowerShell script from another one?
I have a script a.ps1 from which I want to call b.ps1 which does different task.
Let me know your suggestions. Is dot sourcing is the best option here?
Dot sourcing will run the second script as if it is part of the caller—all script scope changes will affect the caller. If this is what you want then dot-source,
However it is more usual to call the other script as if it were a function (a script can use param and function level attributes just like a function). In many ways a script is a PowerShell function, with the name of the file replacing the naming of the function.
Dot sourcing makes it easier to at a later stage convert your script(s) into a module, you won't have to change the script(s) into functions.
Another advantage of dot sourcing is that you can add the function to your shell by adding the file that holds the functions to Microsoft.PowerShell_profile.ps1, meaning you have them available at all times (eliminating the need to worry about paths etc).
I have a short write-host at the top of my dot sourced files with the name of the function and common parameters and I dot source the functions in my profile. Each time I open PowerShell, the list of functions in my profile scrolls by (If like me, you frequently forget the exact names of your functions/files You'll appreciate this as over time as the number of functions start to pile up).
Old but still relevant.
I work with modules with "Import-Module ", this will import the module in the current powershell session.
To avoid keep in cache and to always have the last changes from the module I put a "Get-Module | Remove-Module" that will clear all the loaded modules in the current session.
Get-Module | Remove-Module
Import-Module '.\IIS\Functions.psm1'