PowerShell 5.0 introduced PackageManagement (Oneget) – for managing software installation packages and PowerShellGet for managing PowerShell modules.
Those features are now available on PowerShell 3 and 4
PowerShell 5.0 introduced PackageManagement (Oneget) – for managing software installation packages and PowerShellGet for managing PowerShell modules.
Those features are now available on PowerShell 3 and 4
The WMF 4.0 Updates that were released in November 2014 for Windows 8.1 and Windows Server 2012 R2 are now available for:
Windows Server 2012
Windows Server 2008 R2 SP1
Windows 7 SP1
You need WMF 4.0 installed to install the update
I was asked how to create a NIC team only using the 1GB adapters without knowing how many 1gb NICs were on the server.
I think this should solve the problem
New-NetLbfoTeam -TeamMembers (Get-NetAdapter | where Speed -ge 1gb | select -ExpandProperty Name) -Name MyTeam
Use New-NetLbfoTeam to create the team. The team member names are generated by
Get-NetAdapter | where Speed -ge 1gb | select -ExpandProperty Name
By putting that statement in parentheses as the value for the –TeamMembers parameter the results are used as the value for the parameter. Shouldn’t matter now how many NICs or what they are called. You can modify the filter criteria as required.
For my demo at the PowerShell Summit I wanted to use DHCP for the Linux machine but guarantee that it had a specific IP address. Time to create a DHCP reservation
The DHCP module in Windows Server 2012 and 2012 R2 enables you to create a reservation:
Add-DhcpServerv4Reservation -ScopeId 10.10.54.0 -IPAddress 10.10.54.2 -ClientId 00155D36C906 -Description "LInux machine" -Name "SphinxLX01"
The clientid is the VMs MAC address.
You can view the current reservations:
£> Get-DhcpServerv4Reservation -ScopeId 10.10.54.0 | fl *
IPAddress : 10.10.54.2
ScopeId : 10.10.54.0
AddressState : ActiveReservation
ClientId : 00-15-5d-36-c9-06
Description : LInux machine
Name : SphinxLX01
Type : Both
You can view current leases:
£> Get-DhcpServerv4Lease -ScopeId 10.10.54.0 | fl *
IPAddress : 10.10.54.2
ScopeId : 10.10.54.0
AddressState : ActiveReservation
ClientId : 00-15-5d-36-c9-06
ClientType : Dhcp
Description : LInux machine
DnsRegistration : NotApplicable
DnsRR : NoRegistration
HostName : SphinxLX01
LeaseExpiryTime :
NapCapable : False
NapStatus : FullAccess
PolicyName :
ProbationEnds :
ServerIP : 10.10.54.201
And all from the comfort of your very own PowerShell prompt
I recently re-built my test lab and now need to authorise the DHCP server.
You can test the DHCP server:
£> Get-DhcpServerSetting
IsDomainJoined : True
IsAuthorized : False
DynamicBootp : True
RestoreStatus : False
ConflictDetectionAttempts : 0
NpsUnreachableAction : Full
NapEnabled : False
ActivatePolicies : True
Authorisation is straightforward
Add-DhcpServerInDC -DnsName server02.manticore.org -IPAddress 10.10.54.201
If you only have a single NIC in your DHCP server you don’t need to worry about the IP address
£> Get-DhcpServerSetting
IsDomainJoined : True
IsAuthorized : True
DynamicBootp : True
RestoreStatus : False
ConflictDetectionAttempts : 0
NpsUnreachableAction : Full
NapEnabled : False
ActivatePolicies : True
Create a scope and activate it
Add-DhcpServerv4Scope -ComputerName server02 -Name "Manticore Scope" -StartRange 10.10.54.2 -EndRange 10.10.54.30 -Description "Scope for Manticore domain" -Type DHCP -State Active -SubnetMask 255.255.255.0 -LeaseDuration (New-TimeSpan -Days 2)
ComputerName is the name of the DHCP server otherwise the parameters are self explanatory
To view all scopes
Get-DhcpServerv4Scope -ComputerName server02
To view specific scope
Get-DhcpServerv4Scope -ComputerName server02 -ScopeId 10.10.54.0 | fl
ScopeId : 10.10.54.0
Name : Manticore Scope
Description : Scope for Manticore domain
SuperscopeName :
SubnetMask : 255.255.255.0
StartRange : 10.10.54.2
EndRange : 10.10.54.30
LeaseDuration : 2.00:00:00
NapProfile :
NapEnable : False
Delay(ms) : 0
State : Active
Type : Dhcp
MaxBootpClients : 4294967295
ActivatePolicies : True
I much prefer the CIM cmdlets for accessing remote machines. The WMI cmdlets use DCOM which is firewall unfriendly and can often be unavailable of a server – cue the dreaded RPC server is unavailable error messages.
By contrast the CIM cmdlets use WSMAN.
For one off access to a remote machine use the computername parameter
Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName RSSURFACEPRO2
If you want to access a machine multiple times in the session create a CIM session – analagous to a remoting session
$cs = New-CimSession -ComputerName RSSURFACEPRO2
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $cs
By default a CIM session uses WSMAN
£> $cs
Id : 1
Name : CimSession1
InstanceId : 30c2b530-4ff7-448e-b68d-1f1282890e6a
ComputerName : RSSURFACEPRO2
Protocol : WSMAN
though you can configure them to use DCOM if need be
$opt = New-CimSessionOption -Protocol DCOM
$csd = New-CimSession -ComputerName RSSURFACEPRO2 -SessionOption $opt
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $csd
When would you need to use DCOM – if you are accessing a machine with PowerShell 2 installed. The CIM cmdlets want to use WSMAN 3 and will error if you access a machine with WSMAN 2 installed however if you include a –Filter they will work
So
Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName computer1
will fail if computer1 is running WSMAN 2 (PowerShell 2)
However, if you change the command to include a filter
Get-CimInstance -ClassName Win32_OperatingSystem -Filter "Manufacturer LIKE ‘Microsoft%’" -ComputerName computer1
Even if, as in this case, the filter doesn’t actually do anything
The CIM and WMI cmdlets both provide a way to use the methods on CIM classes namely Invoke-CimMethod and Invoke-WmiMethod. The cmdlets are very similar in operation.
$vol = Get-WmiObject -Class Win32_Volume -Filter "DriveLetter = ‘D:’"
Invoke-WmiMethod -InputObject $vol -Name Chkdsk -ArgumentList $false, $true, $true, $false, $false, $false
The argumenst list isn’t very informative – unless you know the class, read the documentation or investigate with Get-CimClass
Using the CIM cmdlets is a bit more informative as to what is going on.
$vol = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = ‘D:’"
Invoke-CimMethod -InputObject $vol -MethodName Chkdsk -Arguments @{FixErrors=$false; ForceDismount=$false; OkToRunAtB
ootUp = $false; RecoverBadSectors = $false; SkipFolderCycle = $true; VigorousIndexCheck = $true}
You present the arguments as a hash table – this means you can create the hash table and pass it to the method
$margs = @{
FixErrors=$false
ForceDismount=$false
OkToRunAtBootUp = $false
RecoverBadSectors = $false
SkipFolderCycle = $true
VigorousIndexCheck = $true
}
Invoke-CimMethod -InputObject $vol -MethodName Chkdsk -Arguments $margs
This also means that you can create a default set of values and manipulate them in your scripts very easily
Using Invoke-CimMethod involves more typing but I think that’s worth it for the clarity. Of course if you are going to be using the methods of class a lot then I’d recommend that you create a CDXML module from the class – but that’s a whole different set of articles.
Consider this workflow
workflow chkpt1 {
Get-Process
foreach ($x in 1..20){
$x
}
}
It will dump out the process information then output the numbers 1 to 20. Not a particularly enlightening workflow but it forms a nice basis for demonstrating checkpoints.
A checkpoint saves the state and data in the workflow. If the workflow is suspended or interrupted the work flow can be restarted from the most recent checkpoint rather than a complete restart from the beginning.
Change the workflow to give a long running activity
workflow chkpt1 {
Get-Process
foreach ($x in 1..1000){
$x
}
}
Let the process data be displayed and then stop execution once the numbers start displaying – this is easiest if you use ISE. If you want to restart the workflow you have to start it right from the beginning.
Add a checkpoint to the workflow. This can be achieved in a number of ways.
Use the Checkpoint-Workflow activity to the workflow.
workflow chkpt1 {
Get-Process
Checkpoint-Workflow
foreach ($x in 1..1000){
$x
}
}
or use the –PSPersist parameter
workflow chkpt1 {
Get-Process -PSPersist
foreach ($x in 1..1000){
$x
}
}
I prefer to use Checkpoint-Workflow as it is more obvious to me when I review the workflow.
if you want to checkpoint your workflows – you have to start them as a job
chkpt1 –AsJob
Then shut down ISE
Open another PowerShell session with elevated privileges. Use Get-Job to see the suspended job.
View the data in the job
Receive-Job -Id 5 –Keep
Restart the job
Resume-Job -Id 5
Once the job finishes view the data and you’ll see the process data and the list of numbers.
Use Checkpoint-Workflow as many time as necessary to protect your data in long running workflows. A checkpoint is a good idea any time that it would be expensive to restart the whole process.
One of the great things about work flows is that you can stop and start them. A workflow can be stopped, on a temporary basis, by using the Suspend-Workflow activity.
workflow suspend1 {
Get-Service
Suspend-Workflow
Get-Process
}
suspend1
This will run the Get-Service activity – and produce output to the console. The workflow will suspend and automatically create a job. You will see output like this:
HasMoreData : True
StatusMessage :
Location : localhost
StartParameters : {}
Command : suspend1
JobStateInfo : Suspended
Finished : System.Threading.ManualResetEvent
InstanceId : bbe0903d-1720-46da-a6dd-e0a927aa9e11
Id : 8
Name : Job8
ChildJobs : {Job9}
PSBeginTime : 30/06/2014 19:40:29
PSEndTime : 30/06/2014 19:40:29
PSJobTypeName : PSWorkflowJob
Output : {}
Error : {}
Progress : {}
Verbose : {}
Debug : {}
Warning : {}
State : Suspended
Notice the state.
You can manage the job with the standard job cmdlets
£> Get-Job
Id Name PSJobTypeName State HasMoreData Location Command
— —- ————- —– ———– ——– ——-
8 Job8 PSWorkflowJob Suspended True localhost suspend1
The job is restarted using Resume-Job. Once the job has finished you can use Receive-Job to get the rest of the data.
In my last post I questioned why commands from CDXML didn’t fail as thee weren’t any activities defined for them. Turns out that functions and other commands that don’t explicitly have their own workflow activities are implicitly wrapped in the inline script activity. As CDXML modules effectively create a function – that means that workflows accept them and run.
Thanks to Steve Murawski for the answer.