October 23, 2011 11:08 AM
Posted by: Richard Siddaway
Network,
PowerShell v2Normally I ignore the Hosts file but my development laptop isn’t a member of my test domain – a number of reasons for this which I won’t go into.
This means that when I want to RDP to a machine in the test domain I have to use the IP address. A bit awkward but not too bad until I start changing the machines and I need to remember more IP addresses. Time to use the Hosts file then I can just refer to machine name. First off need to be able to read the hosts file.
Could just use
Get-Content -Path C:\Windows\system32\drivers\etc\hosts
but that’s no fun. Lets identify the bits of the file we need and junk the rest.
function get-hostfilecontent {
$file = Join-Path -Path $($env:windir) -ChildPath "system32\drivers\etc\hosts"
if (-not (Test-Path -Path $file)){
Throw "Hosts file not found"
}
Get-Content -Path $file |
where {!$_.StartsWith("#")} |
foreach {
if ($_ -ne ""){
$data = $_ -split " ",2
New-Object -TypeName PSObject -Property @{
Server = $data[1].Trim()
IPAddress = $data[0].Trim()
}
}
}
}
Create the path to the file and test it exists. I’ve used the windir environmental variable just to be sure I can find it.
Run get-content on the file and filter out the comments (start with #). For each remaining record split it in 2 based on the first space. Only allow two substrings from the split in case multiple spaces were used. Take the resultant data and output as an object with 2 properties – server name and IPAddress.
October 19, 2011 2:08 PM
Posted by: Richard Siddaway
Deep dive,
Network,
PowerShell v2,
WMIOne question (of many) that came up at that European Deep Dive (more on that later) was finding the particular network adapter associated with an IP Address. The problem is that IP Address (in the later versions of Windows) is a string array in WMI
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Index=7"
returns this for the IP Address
IPAddress : {10.10.54.202, fe80::4547:ee51:7aac:521e}
So we need a bit of magic. How can we test if an array contains a particular value?
function get-nicfromIP {
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
[string]$ipaddress,
[string]$computername="$env:COMPUTERNAME"
)
Write-Verbose $ipaddress
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $computername |
foreach {
Write-Verbose "$($_.Description)"
if ($($_.IPAddress) -contains $ipaddress){
Write-Debug "getting adapter"
Get-WmiObject -Class Win32_NetworkAdapter -Filter "DeviceID=$($_.Index)" -ComputerName $computername
}
}
}
Create a function that takes an IP Address as a parameter (thanks to Tobias for the regex – one day I’ll learn to do them)
Use the Win32_NetworkAdapterConfiguration class to retrieve the configurations. Foreach configuration test if the IPAddress array contains the IPAddress.
The –contains operator is made for this work
If our test is true then we get the Win32_NetworkAdapter that is associated with the configuration. I’ve just used the fact that DeviceId=Index to perform the link.
Contrary to my thinking at the Deep Dive (why didn’t we test it instead of just talking about it
) there is a WMI association between the Win32_NetworkAdapterConfiguration and the Win32_NetworkAdapter class so we could rewrite the if statement as
function get-nicfromIP {
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
[string]$ipaddress,
[string]$computername="$env:COMPUTERNAME"
)
Write-Verbose $ipaddress
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $computername |
foreach {
Write-Verbose "$($_.Description)"
if ($($_.IPAddress) -contains $ipaddress){
Write-Debug "getting adapter"
$q = "ASSOCIATORS OF {Win32_NetworkAdapterConfiguration.Index=$($_.Index)}"
Get-WmiObject -ComputerName $computername -Query $q
}
}
}
October 12, 2011 1:15 PM
Posted by: Richard Siddaway
Deep dive,
PowerShellNext Monday & Tuesday sees the first European Deep Dive – if you are a PowerShell fan its where you need to be.
The speaker line up is available from
http://blogs.msdn.com/b/powershell/archive/2011/10/06/powershell-deep-dive-lineup.aspx
See you there
October 4, 2011 1:27 PM
Posted by: Richard Siddaway
PowerShell v2,
WMIThe Win32_OSRecoveryConfiguration class represents the types of information that will be gathered from memory when the operating system fails. This includes boot failures and system crashes.
One very important parameter is DebugInfoType which sets the type of debugging information written to the log file.
Possible values are:
| Value |
Meaning |
|
0
|
None
|
|
1
|
Complete Memory Dump
|
|
2
|
Kernel Memory Dump
|
|
3
|
Small Memory Dump
|
If we try and change the setting like this
Set-WmiInstance -Class Win32_OSRecoveryConfiguration -Arguments @{DebugInfoType=1}
we get this error
Set-WmiInstance : Unsupported parameter
Lets try running in an elevated prompt. Nope same error
Last chance we EnableAllPrivileges while in an elevated prompt
Nope still get same error
very last chance
Get-WmiObject -Class Win32_OSRecoveryConfiguration -EnableAllPrivileges |
Set-WmiInstance -Arguments @{DebugInfoType=1}
Now that works!!
We have to enable all privileges on the object BEFORE we try and modify it.
If you have a WMI class where you are trying to modify a property and get these errors:
- Try elevated prompt
- Try –EnableAllPrivileges in elevated prompt
- Try Get-WmiObject with –EnableAllPrivileges piped into Set-WmiInstance in an elevated prompt
October 2, 2011 1:21 PM
Posted by: Richard Siddaway
PowerShell 3,
Windows 8In this post – http://msmvps.com/blogs/richardsiddaway/archive/2011/09/23/powershell-3-and-dhcp-2-scopes.aspx – we created a new DHCP scope.
Now we need to set some options on the scope. One of the main options we need to set is the DNS server
We can see the available options using
Get-DhcpServerv4OptionDefinition -ComputerName server02
This displays a list of the available options – remember that we can add our own so this isn’t necessarily a static list
The options that are set for the test scope are
PS> Get-DhcpServerv4OptionValue -ComputerName server02 -ScopeId 192.168.100.0
OptionId Name Type Value VendorClass UserClass PolicyName
——– —- —- —– ———– ——— ———-
51 Lease DWord {86400}
The DNS server for this scope can be set like this
PS> Set-DhcpServerv4OptionValue -ComputerName server02 -ScopeId 192.168.100.0 `
-DnsServer 10.10.54.201
OptionId Name Type Value VendorClass UserClass PolicyName
——– —- —- —– ———– ——— ———-
6 DNS Servers IPv4Add… {10.10.54.201}
September 27, 2011 1:49 PM
Posted by: Richard Siddaway
PowerShell v2,
WMIWMI is installed as a series of providers. The information on creating the classes comes from MOF files. I was recently asked about a problem with a specific class & could it be restored – in this case it was easier to rebuild WMI as the provider created a large part of the root\cimv2 namespace (namespaces can require multiple namespaces to complete their creation).
That got me thinking about how you discover the mof file associated with a class. Which leads to
$ns = "root\cimv2"
$class = "Win32_Logicaldisk"
$p = Get-WmiObject -Namespace $ns -Class $class |
select -f 1 |
select -ExpandProperty qualifiers |
where {$_.Name -eq 'provider'}
$class
$p
Get-ChildItem -Path C:\Windows\System32\wbem -Filter "*$($p.Value)*"
Get the first instance of a class, expand the qualifiers and select the qualifier with a name of provider.
Then perform a dir on the wbem folder to find the appropriate files. This isn’t infallible due to files names not necessarily being consistent but its a good starting point for the standard classes
September 25, 2011 1:35 PM
Posted by: Richard Siddaway
PowerShell v2,
WMIThere are many people who don’t like to see the WMI system properties
PS> Get-WmiObject -Class Win32_OperatingSystem | select __*
__GENUS : 2
__CLASS : Win32_OperatingSystem
__SUPERCLASS : CIM_OperatingSystem
__DYNASTY : CIM_ManagedSystemElement
__RELPATH : Win32_OperatingSystem=@
__PROPERTY_COUNT : 63
__DERIVATION : {CIM_OperatingSystem, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER : RSLAPTOP01
__NAMESPACE : root\cimv2
__PATH : \\RSLAPTOP01\root\cimv2:Win32_OperatingSystem=@
Now one day we may get a version of Get-WmiObject that allows us to block their display but in the mean time we can create a proxy function.
Using the metaprogramming module from
http://blogs.msdn.com/powershell/archive/2009/01/04/extending-and-or-modifing-commands-with-proxies.aspx
I created a proxy function
New-ProxyCommand Get-WmiObject -CommandType All
-AddParameter NoSystemProperties > Get-WmiObject.ps1
This adds a parameter NoSystemProperties and outputs everything to a .ps1 file.
The details need to be added:
- turn the script into a function
- add the [switch] type to the property
- add the code to deal with the new parameter
if ($NoSystemProperties) {
[Void]$PSBoundParameters.Remove("NoSystemProperties")
$scriptCmd = {& $wrappedCmd @PSBoundParameters |
Select-Object -ExcludeProperty __* -Property *|
Select-Object -ExcludeProperty Scope, Path, Options, ClassPath,
Properties, SystemProperties, Qualifiers, Site, Container -Property * }
}
else {
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
}
If the NoSystemProperties parameter is given then remove it from the bound parameters and then run get-wmiobject, exclude the system properties and then exclude the other related properties
If the NoSystemProperties isn’t set then run as normal
function Get-WmiObject {
[CmdletBinding(DefaultParameterSetName='query')]
param(
[Parameter(ParameterSetName='query', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='list', Position=1)]
[System.String]
${Class},
[Parameter(ParameterSetName='list')]
[Switch]
${Recurse},
[Parameter(ParameterSetName='query', Position=1)]
[System.String[]]
${Property},
[Parameter(ParameterSetName='query')]
[System.String]
${Filter},
[Switch]
${Amended},
[Parameter(ParameterSetName='query')]
[Parameter(ParameterSetName='WQLQuery')]
[Switch]
${DirectRead},
[Parameter(ParameterSetName='list')]
[Switch]
${List},
[Parameter(ParameterSetName='WQLQuery', Mandatory=$true)]
[System.String]
${Query},
[Switch]
${AsJob},
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='query')]
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='path')]
[System.Management.ImpersonationLevel]
${Impersonation},
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='query')]
[Parameter(ParameterSetName='list')]
[System.Management.AuthenticationLevel]
${Authentication},
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='query')]
[System.String]
${Locale},
[Parameter(ParameterSetName='query')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='class')]
[Switch]
${EnableAllPrivileges},
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='query')]
[System.String]
${Authority},
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='query')]
[Parameter(ParameterSetName='list')]
[System.Management.Automation.PSCredential]
${Credential},
[System.Int32]
${ThrottleLimit},
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='query')]
[Alias('Cn')]
[ValidateNotNullOrEmpty()]
[System.String[]]
${ComputerName},
[Parameter(ParameterSetName='list')]
[Parameter(ParameterSetName='path')]
[Parameter(ParameterSetName='class')]
[Parameter(ParameterSetName='WQLQuery')]
[Parameter(ParameterSetName='query')]
[Alias('NS')]
[System.String]
${Namespace},
[Switch]
${NoSystemProperties})
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-WmiObject', [System.Management.Automation.CommandTypes]::Cmdlet)
if ($NoSystemProperties) {
[Void]$PSBoundParameters.Remove("NoSystemProperties")
$scriptCmd = {& $wrappedCmd @PSBoundParameters |
Select-Object -ExcludeProperty __* -Property *|
Select-Object -ExcludeProperty Scope, Path, Options, ClassPath, Properties, SystemProperties, Qualifiers, Site, Container -Property * }
}
else {
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
}
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
$steppablePipeline.End()
} catch {
throw
}
}
<#
.ForwardHelpTargetName Get-WmiObject
.ForwardHelpCategory Cmdlet
#>
}
The new function can be dot sourced or loaded from a module and because PowerShell runs functions before cmdlets it intercepts the cmdlet.
Get-WmiObject -Class Win32_OperatingSystem
Get-WmiObject -Class Win32_OperatingSystem –NoSystemProperties
then give us what we want.
The drawback is that using –NoSystemProperties we lose the methods but if you want them then you are either putting the results into an object or onto the pipeline in which case the system properties won’t be displayed.
Until we get a change to the cmdlet this will work.
Enjoy.
September 22, 2011 12:29 PM
Posted by: Richard Siddaway
PowerShell,
User GroupThe recording of Aleksandar’s session for the UK user group
http://msmvps.com/blogs/richardsiddaway/archive/2011/09/08/powershell-user-group-20-september-2011.aspx
entitled
PowerShell remoting and the customisation of remoting end points
Is available from
https://skydrive.live.com/?cid=43cfa46a74cf3e96#!/?cid=43cfa46a74cf3e96&sc=documents&uc=1&id=43CFA46A74CF3E96%212927
The slides and demo scripts are included in the zip file.
The next meeting will be 25 Oct 2011 on WSMAN and WMI. It is an extended version of the recent session I did for the pre-TechEd Australia PowerShell conference. As well as WMI and WSMAN we will have a look at the new remoting access methods in PowerShell v3. Details to follow.