Tag Archives: Tasks

Troubleshoot System Center Orchestrator RunBook issues

Repeated tasks are the bane of IT pros’ existence. System Center Orchestrator alleviates some of that burden by…

“;
}
});

/**
* remove unnecessary class from ul
*/
$(“#inlineregform”).find( “ul” ).removeClass(“default-list”);

/**
* Replace “errorMessageInput” class with “sign-up-error-msg” class
*/
function renameErrorMsgClass() {
$(“.errorMessageInput”).each(function() {
if ($(this).hasClass(“hidden”)) {
$(this).removeClass(“errorMessageInput hidden”).addClass(“sign-up-error-msg hidden”);
} else {
$(this).removeClass(“errorMessageInput”).addClass(“sign-up-error-msg”);
}
});
}

/**
* when validation function is called, replace “errorMessageInput” with “sign-up-error-msg”
* before return
*/
function validateThis(v, form) {
var validateReturn = urValidation.validate(v, form);
renameErrorMsgClass();
return validateReturn;
}

/**
* DoC pop-up window js – included in moScripts.js which is not included in responsive page
*/
$(“#inlineRegistration”).on(“click”,”a.consentWindow”, function(e) {
window.open(this.href, “Consent”, “width=500,height=600,scrollbars=1”);
e.preventDefault();
});

automating several key runbook management and troubleshooting activities while preserving event history for review as needed. 

System Center Orchestrator consolidates runbook tasks into a single task, then executes against a target using System Center Orchestrator RunBook. You can add instructions to control the sequence of activities in a runbook. You can also create unlimited runbooks and execute one or all of them at the same time. When it comes to troubleshooting System Center Orchestrator RunBook issues, reference the log files where runbook-related activities are recorded. You can view log files to learn the status of each runbook, collect real-time log events for runbooks that are executing and also check runbook audit history. In Runbook Designer, you can view real-time log events, historic events and runbook auditing history.

Real-Time Log: The Real-Time Log shows activities related to running instances of runbooks and the time a runbook was started.

Historic Log: The Historic Log includes start and end times of a runbook. You might want to check whether a runbook executed all the activities or not. If a runbook terminates unexpectedly, you won’t see the end time. If you want to see which activity failed, double click on the runbook to see details about the activity.

Runbook Audit History: If a runbook ran successfully previously but failed to execute recently, it makes sense to check the Runbook Audit History page. The Runbook Designer keeps track of changes to each activity in the runbook and the user who made the changes, including the date and time when the changes were made. Runbook Audit History also includes previous values, so it’s easy to revert back to them.

When troubleshooting runbook failures, enable the Activity-specific Published Data option for each activity. By default, published data isn’t included for each activity. You need to enable published data for runbooks from the logging property of the runbook as shown in Figure A:

Runbook logging property options
Figure A. Enable published data for runbooks from the logging property

While System Center Orchestrator RunBook logs might help you troubleshoot issues, a freeware utility called Orchestrator Health Checker helps you understand active runbooks and performs other runbook-related actions.

Dig Deeper on Virtual machine monitoring, troubleshooting and alerting

Have a question for an expert?

Please add a title for your question

Get answers from a TechTarget expert on whatever’s puzzling you.

Will PowerShell Core 6 fill in missing features?

Administrators who have embraced PowerShell to automate tasks and manage systems will need to prepare themselves…

“;
}
});

/**
* remove unnecessary class from ul
*/
$(“#inlineregform”).find( “ul” ).removeClass(“default-list”);

/**
* Replace “errorMessageInput” class with “sign-up-error-msg” class
*/
function renameErrorMsgClass() {
$(“.errorMessageInput”).each(function() {
if ($(this).hasClass(“hidden”)) {
$(this).removeClass(“errorMessageInput hidden”).addClass(“sign-up-error-msg hidden”);
} else {
$(this).removeClass(“errorMessageInput”).addClass(“sign-up-error-msg”);
}
});
}

/**
* when validation function is called, replace “errorMessageInput” with “sign-up-error-msg”
* before return
*/
function validateThis(v, form) {
var validateReturn = urValidation.validate(v, form);
renameErrorMsgClass();
return validateReturn;
}

/**
* DoC pop-up window js – included in moScripts.js which is not included in responsive page
*/
$(“#inlineRegistration”).on(“click”,”a.consentWindow”, function(e) {
window.open(this.href, “Consent”, “width=500,height=600,scrollbars=1”);
e.preventDefault();
});

as Microsoft plans to focus its energies in the open source version called PowerShell Core.

All signs from Microsoft indicate it is heading away from the Windows-only version of PowerShell, which the company said it will continue to support with critical fixes — but no further upgrades. The company plans to release PowerShell Core 6 shortly. Here’s what admins need to know about the transition.

What’s different with PowerShell Core?

PowerShell Core 6 is an open source configuration management and automation tool from Microsoft. As of this article’s publication, Microsoft made a release candidate available in November. PowerShell Core 6 represents a significant change for administrators because it shifts from a Windows-only platform to accommodate heterogeneous IT shops and hybrid cloud networks. Microsoft’s intention is to give administrative teams a single tool to manage Linux, macOS and Windows systems.

What features are not in PowerShell Core?

PowerShell Core runs on .NET Core and uses .NET Standard 2.0, the latter is a common library that helps make some current Windows PowerShell modules work in PowerShell Core.

As a subset of the .NET Framework, PowerShell Core misses out on some useful features in Windows PowerShell. For example, workflow enables admins to execute tasks or retrieve data through a sequence of automated steps. This feature is not in PowerShell Core 6. Similarly, tasks such as sequencing, checkpointing, resumability and persistence are not available in PowerShell Core.

A few other features missing from PowerShell Core 6 are:

  • Windows Presentation Foundation: This is the group of .NET libraries that enable coders to build UIs for scripts. It offers a common platform for developers and designers to work together with standard tools to create Windows and web interfaces.
  • Windows Forms: In PowerShell 5.0 for Windows, the Windows Forms feature provides a robust platform to build rich client apps with the GUI class library on the .NET Framework. To create a form, the admin loads the System.Windows.Forms assembly, creates a new object of type system.windows.forms and calls the ShowDialog method. With PowerShell Core 6, administrators lose this capability.
  • Cmdlets: As of publication, most cmdlets in Windows PowerShell have not been ported to PowerShell Core 6. However, the compatibility with .NET assemblies enables admins to use the existing modules. Users on Linux are limited to modules mostly related to security, management and utility. Admins on that platform can use the PowerShellGet in-box module to install, update and discover PowerShell modules. PowerShell Web Access is not available for non-Windows systems because it requires Internet Information Services, the Windows-based web server functionality.
  • PowerShell remoting: Microsoft ports Secure Socket Shell to Windows, and SSH is already popular in other environments. That means SSH-based remoting for PowerShell is likely the best option for remoting tasks. Modules such as Hyper-V, Storage, NetTCPIP and DnsClient have not been ported to PowerShell Core 6, but Microsoft plans to add them.

Is there a new scripting environment?

For Windows administrators, the PowerShell Integrated Scripting Environment (ISE) is a handy editor that admins use to write, test and debug commands to manage networks. But PowerShell ISE is not included in PowerShell Core 6, so administrators must move to a different integrated development environment.

Microsoft recommends admins use Visual Studio Code (VS Code). VS Code is a cross-platform tool and uses web technologies to provide a rich editing experience across many languages. However, VS Code lacks some of PowerShell ISE’s features, such as PSEdit and remote tabs. PSEdit enables admins to edit files on remote systems without leaving the development environment. Despite VS Code’s limitations, Windows admins should plan to migrate from PowerShell ISE and familiarize themselves with VS Code.

What about Desired State Configuration?

Microsoft offers two versions of Desired State Configuration: Windows PowerShell DSC and DSC for Linux. DSC helps administrators maintain control over software deployments and servers to avoid configuration drift.

Microsoft plans to combine these two options into a single cross-platform version called DSC Core, which will require PowerShell Core and .NET Core. DSC Core is not dependent on Windows Management Framework (WMF) and Windows Management Instrumentation (WMI) and is compatible with Windows PowerShell DSC. It supports resources written in Python, C and C++.

Debugging in DSC has always been troublesome, and ISE eased that process. But with Microsoft phasing out ISE, what should admins do now? A Microsoft blog says the company uses VS Code internally for DSC resource development and plans to release instructional videos that explain how to use the PowerShell extension for DSC resource development.

PowerShell Core 6 is still in its infancy, but Microsoft’s moves show the company will forge ahead with its plan to replace Windows PowerShell. This change brings a significant overhaul to the PowerShell landscape, and IT admins who depend on this automation tool should pay close attention to news related to its development.

Dig Deeper on Microsoft Windows Scripting Language

New Cisco managed services seek to ease IT talent shortage

Cisco has introduced managed services that remove mundane networking tasks from engineers’ to-do list, freeing up time to work on projects to streamline and advance business operations.

Cisco unveiled this week Business Critical and High-Value Services the company said would let customers make better use of network managers’ time. The Cisco managed services are expected to help the vendor reach its goal of boosting software and services revenue to half of overall sales by 2020.

To entice companies, Cisco is marketing the services as a way to address the shortage in IT talent by making more efficient use of networking staff. In a Cisco-sponsored white paper, IDC found 69% of more than a 1,000 IT leaders surveyed worked in organizations lacking sufficient expertise to digitize business processes.

The latest Cisco managed services attack the problem by taking over routine networking tasks that take up roughly a quarter of engineers’ time. Similar services are also available through other vendors, including Hewlett Packard Enterprise, Huawei and Juniper Networks.

“I wouldn’t say the features and functionality are new [in the market],” IDC analyst Leslie Rosenberg said of the latest services. “It’s more of an evolution of their existing offers.”

Cisco Business Critical Services

With Business Critical Services, Cisco is offering to remotely handle, for example, chores related to deploying new networking hardware. The tasks would include configuring the devices and applying already-defined policies.

The use of third parties to automate routine jobs is a trend Rosenberg sees in the overall services market. “In my opinion, it’s going to begin to change the way enterprise customers consume and drive value from services,” she said. “Anything that you’re doing twice manually, you should be automating.”

New Cisco managed services also include the collection of telemetry data from customers’ networks and using it to advise them on corrective actions to prevent potential problems. Cisco can also use the collected data to inform customers on how to keep the network running at its peak performance level.

Cisco High-Value Services

Cisco’s High-Value Services is an additional support option. Under the service, Cisco, or one of its partner, will install a new product and make sure all licensed features are turned on and running. Cisco would still offer more advanced services for more complex deployments that require, for example, integration with third-party software or hardware.

“If [companies] just want to get it up and running faster and right the first time, then they have the opportunity to buy the service from Cisco,” Rosenberg said.

Cisco acquires Perspica

Meanwhile, Cisco announced this week it would acquire Perspica, a company based in San Jose, Calif., that applies machine learning to analyze streaming data, rather than waiting until it is stored. Cisco plans to use Perspica technology and expertise with its AppDynamics software for monitoring and analyzing application data. Cisco acquired the company AppDynamics this year for $3.7 billion.

Perspica and its engineers will become a part of Cisco’s AppDynamics unit. Combining technology from the two acquisitions will provide analytics that is “infinitely scalable and ridiculously fast to keep pace with developments in the enterprise,” Bhaskar Sunkara, CTO of AppDynamics, said in a blog post.

Cisco did not disclose financial details of the latest acquisition.

The Best To-Do List Apps of 2017



Manage Your Tasks With an App

If you haven’t gone paperless with your to-do list yet, you’re missing out. These apps let you edit and rearrange your to-dos based on changing priorities, share lists with family members or other collaborators, and get reminders for your upcoming deadlines, no matter which device you have on you at the moment. Managing tasks in an app is more efficient, more powerful, and simply a better way to be more productive than doing it on paper.

Recently, Microsoft acquired one of the best to-do apps on the market, Wunderlist, and has decided to stop supporting it as of April 2017. The app is still available, but it will no longer receive updates or bug fixes. That’s why it’s not in the table above. Anyone still using Wunderlist should start thinking about migrating to another app sooner rather than later. The company’s own offering, the free Microsoft To-Do, has basic to-do functionality, but it lacks so much that the best apps offer that it’s not really a competitor yet. It’s still in beta, so there’s hope for yet; in the meanwhile, however, Wunderlist users and those new to to-do list apps should thoroughly explore all their options and find the task-management app that best meets their needs. Fortunately, there are some excellent choices for a variety of work styles.

For example, if your idea of digital task management ideally starts in your email, you should check out ActiveInbox, which turns your Gmail inbox into a fully functioning to-do list. I think that your inbox should not be your to-do list, but everyone has different ideas. If you need an app that you can use with a number of people for shared responsibilities, you’ll want an app like Asana or Todoist that has strong collaboration features.

To-Do List Apps vs. Project Management Apps

A great to-do app for personal use, households, and even small teams doesn’t need to be super complicated, the way project management software is, even though they both essentially serve the same function. They both keep track of what needs to get done, when, and by whom. They help us manage time more efficiently and regulate how many tasks are on our plate at once. But personal to-do apps are simpler and cheaper than project management software. They’re a better choice for many use cases.

The difference between to-do list apps, sometimes also called task-management apps, and project management apps is that to-do apps track any kind of tasks whereas project management apps track tasks that are related to projects. Project management apps typically track a lot of metadata related to the project, too.

To-do apps keep track of tasks, assignees, deadlines, and even discussion points related to the tasks. Project management apps do all of that, but they also add a lot more functionality, such as tracking how many tasks various people have on their plate, how much time it takes them to complete tasks, billable hours that are associated with certain tasks or projects, and so forth. Project management apps help guide projects, which generally have a final due date and deliverable. With to-do apps, people are generally just keeping track of tasks that need to get done but that aren’t necessarily part of something that will one day end, the way a project ends.

You don’t need to keep track of billable hours when picking up milk on the way home from work, and you don’t need Gantt charts to get your kids to do their chores. At least, I hope you don’t.

What To Look for in a To-Do App

There are a few qualities I look for in a good to-do list. For starters, you have to like the way it looks. I’m serious. How are you going to get stuff done if you can’t even stand to look at the list itself because it’s ugly? A looked-at list is a useful list.

Second, I like to-do apps that give me a range of tools for organizing my tasks. For example, I want to be able to quickly sort my work tasks from my personal tasks, or view them all according to deadline, or which ones are overdue. I also want to be able to rearrange the order of my tasks quickly and easily. I should be able to schedule reminders so that I get a notification about what I need to do when it’s time, or when I’m in the location where the task should get done.

Third, it’s always nice to have the option to make lists collaborative. If you run a household, a collaborative to-do list gives you the ability to assign tasks to other people. You can open your app and assign your kid the task of walking the dog. You can assign your partner the task of calling back the accountant. Whether you want those same people to have the power to assign tasks to you is another question that I will now sidestep and refuse to answer by changing the subject.

The Best Collaborative To-Do App

PCMag has two Editors’ Choice picks for best collaborative to-do app. One goes to Todoist Premium, which is ideal for a small group of people. The other is Asana, which is better for managing more in-depth teamwork.

Todoist is a powerful to-do app for shared responsibilities, and a bonus feature is that it has a tool that monitors your productivity. Todoist has apps for all major platforms so you can use it anywhere. It’s reliable. It’s efficient. New features are being added all the time. Todoist Premium costs $28.99 per year. A free limited version is also available. I recommend starting with the free account to try it out, but make sure to consider the Premium features, as they really do add a lot of functionality and efficiency.

Asana is excellent for teamwork. Some people classify Asana as a workflow management app, and it is, but it can also function as a team to-do list. Asana has a free version, good for up to 15 people. At $99 per person per year, Asana Premium costs more than Todoist Premium, but as I said, it has additional functionality for managing more the elaborate teamwork typical of businesses.

The Best Free To-Do App

Among free apps, stick with Asana if you need to collaborate, but choose a simpler app, such as Remember the Milk, if you plan to use your to-do app solo. The problem some people encounter with Asana is that it can be too flexible. You might have a hard time figuring out just what to do with an app that comes with so many possibilities but not a lot of rules. In fact, PCMag has written entire features on how to get the most out of Asana.

Remember the Milk is extremely easy to learn to use, and the free version has all the functionality a single user needs. You won’t have any questions about what to do with it or why. Write down things you need to do. Assign deadlines. Check them off when done. It’s that’s simple.

Many of the other to-do apps on this list are excellent, but their free versions are a little limiting compared with the power of their paid versions.

Get Organized With a Great To-Do List App

Having a great to-do list app can help you get organized and get more done, whether you’re managing only your own tasks or those for a family or small team. Below are the best ones worth exploring.

A to-do app is only as useful as the information you put into it, so in addition to picking the right app, you might also want to peruse these tips for creating better to-do lists.

Featured To-Do List App Reviews:

  • Asana Review


    $0.00 MSRP

    Bottom Line: Asana helps teams manage tasks and workflows, and it’s the preeminent tool for the job. Thoughtful design and highly capable features make it a compelling productivity app.

     Read Full Review

  • Todoist Review


    $29.00 MSRP

    Bottom Line: With a clean and simple UI and support for plenty of platforms, Todoist is one of the most feature-rich task management apps on the market, and a clear Editors’ Choice.

     Read Full Review

  • Any.do (for iPhone) Review


    $26.88 MSRP

    Bottom Line: Any.do is a useful and well designed to-do app, though the free version is a bit limited. Its standout feature is the Any.do Moment, which encourages you to review your daily task list befor…

     Read Full Review

  • Remember the Milk Review


    $39.99 MSRP

    Bottom Line: Remember the Milk is a capable to-do-list app with some sharing options included at no cost, making it good for household use. The Pro version unlocks extra features but is on the expensive …

     Read Full Review

  • ActiveInbox Review


    $49.92 MSRP

    Bottom Line: Do you use your Gmail inbox as your to-do list? ActiveInbox adds tools that can make this a better experience.

     Read Full Review

  • Gneo (for iPhone) Review


    $0.00 MSRP

    Bottom Line: Beautiful and fluid, the free Gneo to-do app for iPhone is a treat for the fingers. But it may have put form over function, and serious task masters will likely want something else, and the …

     Read Full Review

  • Google Keep (Web) Review


    $0.00 MSRP

    Bottom Line: Google Keep is a free note-taking and syncing app with a nifty OCR feature, but it lacks the features and mobile apps offered by the competition.

     Read Full Review

Tricks and tools to prevent data loss in Office 365

online service, instead of wrestling with day-to-day tasks. This doesn’t mean that IT teams can ignore the possibility of data loss in Office 365.

While there is a sense of security that comes with a cloud service, organizations need to develop their own data retention plans for some Office 365 features.

Businesses rely on their email systems to stay in touch with employees, clients and suppliers. SharePoint remains an integral component for enterprise content management in many organizations. Companies that shift these workloads — and their data — to Microsoft’s cloud platform should be aware that email and content stored in SharePoint or OneDrive are not, by default, protected against accidental or intentional deletions.

With a move to Office 365, some in IT have abandoned disaster recovery (DR) and business continuity plans (BCP) that were required to recover on-premises email and SharePoint platforms. IT teams only need redundant connectivity to the cloud and must trust that Microsoft’s infrastructure, data centers and systems will provide necessary data protection from hardware and software failures.

In Exchange Online, IT teams can only restore an entire mailbox within 30 days after deletion; after that point, they can ask Microsoft for an additional 14 days for a 44-day window of data recovery. SharePoint and OneDrive face similar challenges, as they do not offer easy or efficient ways to restore site collections or lists that have been deleted and removed from the recycle bin.

Filling Office 365’s DR and BCP gaps

Many companies have gaps in their DR plans; an inability to restore data from a specific point of time can lead to risks. While Microsoft offers service-level agreements of 99.9%, Office 365 has limited capabilities around backups — even though some suggest that on-hold features and retention or preservation policies can prevent data loss in Office 365. These options, however, are limited and do not offer easy ways to recover or restore data.

There are several tools on the market – based both in the cloud and on premises — for Office 365 data protection and DR, including SkyKick, Datto, Spanning and AvePoint. These tools offer automated backup of emails, calendars, OneDrive and, in some cases, SharePoint site collections — without the need for any on-premises infrastructure.

Many of the third-party tools can help IT address some of their backup needs around the Office 365 workloads — email, SharePoint and OneDrive. Admins can be confident that some of their digital assets are protected and that their DR plans are complete. But, in reality, as more users expand into other Office 365 services — such as Planner, Office Groups, PowerApps and Flow — Microsoft or other third-party tools need to play catch-up to protect data stored in those services. Currently, those services don’t offer any backup methods.

When evaluating Office 365, plan for Office 365 backups and implement them immediately after going live. Skipping that step would lead to serious risks and an incomplete DR plan. Those organizations that make the switch without the use of backup services put themselves at risk for data loss in Office 365.

Powered by WPeMatico

An Office 365 pilot can make or break a rollout

Exchange administrators were once preoccupied with time-consuming tasks that involved managing a complex messaging…

“;
}
});

/**
* remove unnecessary class from ul
*/
$(“#inlineregform”).find( “ul” ).removeClass(“default-list”);

/**
* Replace “errorMessageInput” class with “sign-up-error-msg” class
*/
function renameErrorMsgClass() {
$(“.errorMessageInput”).each(function() {
if ($(this).hasClass(“hidden”)) {
$(this).removeClass(“errorMessageInput hidden”).addClass(“sign-up-error-msg hidden”);
} else {
$(this).removeClass(“errorMessageInput”).addClass(“sign-up-error-msg”);
}
});
}

/**
* when validation function is called, replace “errorMessageInput” with “sign-up-error-msg”
* before return
*/
function validateThis(v, form) {
var validateReturn = urValidation.validate(v, form);
renameErrorMsgClass();
return validateReturn;
}

/**
* DoC pop-up window js – included in moScripts.js which is not included in responsive page
*/
$(“#inlineRegistration”).on(“click”,”a.consentWindow”, function(e) {
window.open(this.href, “Consent”, “width=500,height=600,scrollbars=1”);
e.preventDefault();
});

environment. But when Office 365 entered the picture, many of those same admins can use a single web portal to manage and configure systems.

This shift into the cloud also offers new opportunities and frees administrators for other tasks, but the success of the implementation depends on how prepared they are for the change. An Office 365 pilot is the best way to determine if a full implementation will succeed or fail.

Ideally, an Office 365 pilot should roll out to about 5% of end users. This ensures IT spends adequate time to plan and evaluate the new platform within the environment and with a set number of users. It also provides the opportunity to test-drive the platform and determine any potential configuration requirements, issues and implementation caveats that admins need to address prior to a full migration.

During the pilot stage, an organization can either purchase licenses for a number of end users under an existing Microsoft agreement or sign up for a trial version. This enables admins to implement the pilot project and perform most of the required tasks to get end users on the Office 365 service. During the Office 365 pilot phase, IT should use the following points to evaluate and prepare:

Keep an eye on bandwidth

The biggest factors that affect Office 365 performance are connectivity and internal networking configurations. Regardless of the speed of the Office 365 service in Microsoft’s data centers, if the organization’s network bandwidth cannot meet Microsoft’s requirements then end users won’t have a good experience. An Office 365 pilot forces IT to evaluate and identify the specifications required to use the cloud platform. Admins can download several tools for these tasks from Microsoft’s site, such as the calculator that estimates how much bandwidth an organization needs based on the number of end users.

Admins who skip the pilot phase could encounter additional costs later if the organization’s bandwidth is not adequate. And slow network speed for Office 365 could result in slow email delivery and poor tools performance. End users lose confidence and the implementation likely will fail.

More hands-on work in the portal builds confidence

The biggest factors that affect Office 365 performance are connectivity and internal networking configurations.

Exchange Online includes greater functionality and capabilities than its on-premises counterpart, including additional features like Exchange Online Protection, advanced threat protections, data loss prevention, archiving, e-discovery, user mailbox administration and reporting. The portal offers a centralized and consolidated management console that differs significantly from what is available with on-premises Exchange Server.

IT is less likely to be overwhelmed during the full implementation if admins perform due diligence during the Office 365 pilot phase. Review and map out the organization’s policies and familiarize yourself with administrative options.

Address compatibility with email clients and mail-enabled devices

Connectivity and compatibility with legacy applications and devices, such as mobile devices, mail-enabled scanners and printers, often go unaddressed before a move to Office 365. And they can become bigger problems after a migration.

Many of these systems interact with Exchange to communicate and transmit data to end users. But not all these systems have native support for Office 365 and its security requirements. This can lead to a lack of email support unless IT admins perform alternate configurations and setups. An Office 365 pilot helps identify gaps and allows IT to build and test alternate setups to prevent interruptions when the system goes live.

Be aware of customization or custom code in Office

An Office upgrade can be an IT pain point. Several companies in various industries still run Microsoft Office 2010 or even 2007. To use Office 365, these organizations need to upgrade to a new Office environment that requires internet connectivity at least once every 30 days. To keep an Office 365 plan active, someone must sign in at least once every 30 days.

A common challenge with the new Office 365 ProPlus, which allows end users to access Office apps on all devices, is the lack of support for some of the component object model components or legacy add-ons. For example, Sage 100 ERP required clients delay an Office 365 ProPlus while it sorted through some legacy issues. The Office 365 pilot project would help uncover potential incompatibilities and enable IT to take the appropriate steps to upgrade or to rewrite some custom code.

Embrace O365 service, support

Once IT moves to Office 365, its fate is in Microsoft’s hands with regards to guarantees on end-user uptime, including the time it takes to fix any service interruptions. Because the current Office 365 platform has built a reputation for reliability by consistently meeting its guarantee of 99.9% uptime, this is no longer a concern. This doesn’t mean that issues won’t pop up from time to time but, in the pilot stage, IT must learn how to work through the support portal and understand the different service health and monitoring indicators available online. This helps IT teams better prepare for issues or interruption.

The primary focus of an Office 365 pilot project is to test how well the platform will work within the organization. The larger the organization, the more critical the pilot phase is to the success of the project. If admins skip this phase, they risk unwanted surprises for everyone involved — and that could lead to negative consequences and a lack of confidence in the platform.

Next Steps

When to consider a single Office 365 tenant

Five areas to consider before a move to Exchange 2016

Tips to manage Office 365 for Exchange admins

Powered by WPeMatico

The Basics of Background Audio

Background audio in a Universal Windows Platform (UWP) app is a powerful way to provide a more seamless audio experience to your users. This post will walk you through setting up background audio, reacting to device media controls, communicating with the background media player, and managing playlists.

Before we get started, you need to know that background playback consists of two processes:

  1. the foreground app (the app UI and client logic)
  2. the background playback task (the audio playback logic and background services)

In the sample app we’re developing, the user selects and controls the audio, which is then played in the background. By definition, background audio continues playing even when the app is no longer in the foreground.

The background task communicates with Windows through the System Media Transport Controls (SMTC), which lets your app use the media controls and update metadata for the display. It also listens for foreground app events broadcast by the BackgroundMediaPlayer.

Note: You’ll likely want to install Update 1 for Visual Studio 2015 before working your way through this code. It contains the latest Windows Phone emulators.

Setting up the Background Audio

The background playback task is implemented through IBackgroundTask, like any other UWP background task, except in this case, we add logic for audio services. Here, we take a look at how that’s done.

Setting up the Background Task

The IBackgroundTask interface gives us an entry point for running code in the background. It provides one method, IBackgroundTask.Run, that is called by Windows to perform the task’s work. We use the Run method to set up the objects we need to manage the media playback.

The IBackgroundTask.Run method is invoked the first time that one of the following occurs:

  • the Current is accessed from the foreground app
  • a handler is registered for the MessageReceivedFromBackground event

Here’s a quick visual to show how this all fits together:

ba_1

We’ll take a close look at the background audio task by walking through the code in the sample on GitHub.

External References

The first block of code is a standard set of ‘using’ directives to import our namespaces and Windows types. Note the Background Audio resources listed in the last block. The BackgroundAudioShared namespace provides utilities for formatting data and persisting the app state. The BackgroundAudioShared.Messages namespace provides helper classes for decoding messages from the foreground app.

using System;
using System.Diagnostics;
using System.Threading;
using System.Linq;
using Windows.ApplicationModel.Background;
using Windows.Media;
using Windows.Media.Playback;

using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Media.Core;
using System.Collections.Generic;

using BackgroundAudioShared;
using Windows.Foundation;
using BackgroundAudioShared.Messages;
using Windows.Storage.Streams;

The Background Task

We implement the IBackgroundTask interface in the BackgroundAudioTask class. This class needs to refer to the media controls, the playback list, application state, and events. We declare the necessary member variables for this in this top section of the class definition. These will get initialized during the Run method callback. We will discuss how each of these are used in more detail in later sections of this article.

namespace BackgroundAudioTask
{
    public sealed class MyBackgroundAudioTask : IBackgroundTask
    {
        #region Private fields, properties
        private const string TrackIdKey = "trackid";
        private const string TitleKey = "title";
        private const string AlbumArtKey = "albumart";
        private SystemMediaTransportControls smtc;
        private MediaPlaybackList playbackList = new MediaPlaybackList();
        private BackgroundTaskDeferral deferral; // Used to keep task alive
        private AppState foregroundAppState = AppState.Unknown;
        private ManualResetEvent backgroundTaskStarted = new ManualResetEvent(false);
        private bool playbackStartedPreviously = false;
        #endregion

We also set up a couple of helper methods to get the track IDs from playback items. The first gets the track ID of the current item on the playback list. It calls the second helper that gets the track ID from any playback item.

        #region Helper methods
        Uri GetCurrentTrackId()
        {
            if (playbackList == null)
                return null;

            return GetTrackId(playbackList.CurrentItem);
        }

        Uri GetTrackId(MediaPlaybackItem item)
        {
            if (item == null)
                return null; // no track playing

            return item.Source.CustomProperties[TrackIdKey] as Uri;
        }
        #endregion

The App Manifest

Before we get to the app manifest, the background audio task should be set up as a Windows runtime project. Currently it must be in a separate project in the solution because the task is compiled into a DLL that is loaded into a special system background task host process. When you run the app, this process will show in Task Manager as Windows.Media.BackgroundPlayback.exe.

We need to set up a few things in the App Manifest after creating the background audio task. MyBackgroundAudioTask needs to be you registered in the Package.appxmanifest to handle audio events. In the declarations section, you need to specify the following:

Declarations section Entries
Supported declarations Background Tasks
Supported task types (properties) Audio
Entry point BackgroundAudioTask.MyBackgroundAudioTask

The Run Method

The Run method is the heart of the BackgroundAudioTask class. This method will be called by Windows the first time the Media Player is accessed from the foreground. This is where we connect up to the media player by setting properties and adding event handlers.

  1. We set up the Run method below.
        
#region IBackgroundTask and IBackgroundTaskInstance Interface Members and handlers
        /// <summary>
        /// The Run method is the entry point of a background task. 
        /// </summary>
        /// <param name="taskInstance"></param>
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            Debug.WriteLine("Background Audio Task " + taskInstance.Task.Name + " starting...");
  1. In this step we subscribe to key events and set up properties to enable the app to show in the UVC and to respond to system media transport control commands, for example, when you press the volume button on your device.
            // Initialize SystemMediaTransportControls (SMTC) for integration with
            // the Universal Volume Control (UVC).
            //
            // The UI for the UVC must update even when the foreground process has been terminated
            // and therefore the SMTC is configured and updated from the background task.
            smtc = BackgroundMediaPlayer.Current.SystemMediaTransportControls;

            smtc.ButtonPressed += smtc_ButtonPressed;
            smtc.PropertyChanged += smtc_PropertyChanged;
            smtc.IsEnabled = true;
            smtc.IsPauseEnabled = true;
            smtc.IsPlayEnabled = true;
            smtc.IsNextEnabled = true;
            smtc.IsPreviousEnabled = true;
  1. Read the persisted state of the foreground app, so that later we will be able to evaluate whether we can send updates to the active foreground application.

            var value = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.AppState);
            if (value == null)
                foregroundAppState = AppState.Unknown;
            else
                foregroundAppState = EnumHelper.Parse<AppState>(value.ToString());
  1. Add handlers for MediaPlayer to sync the cached playback status on SMTC—playing, paused, or closed—with CurrentMediaPlayer.
BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
  1. Initialize the message channel so the background task can respond to messages sent by the foreground, for example, in response to UI events.
BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;

Note: We recommend that you register for the message received handler before calling BackgroundMediaPlayer.Current for the first time so that the foreground app doesn’t miss any messages sent from the background process.

  1. In the code below, we send a message to the foreground app, if it is active, that the background task has started. This way the foreground app is aware that it can now send further commands, for example, to begin playback.
            if (foregroundAppState != AppState.Suspended)
                MessageService.SendMessageToForeground(new BackgroundAudioTaskStartedMessage());

            ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.BackgroundTaskState, BackgroundTaskState.Running.ToString());
  1. To keep the background task alive after the Run method completes, we need to ask IBackgroundTaskInstance for a deferral. We need to do this before subscribing to the events below because they use it.
            
deferral = taskInstance.GetDeferral(); 
  1. We then mark the background task as started to unblock the SMTC play operation (see related WaitOne on this signal).
backgroundTaskStarted.Set();
  1. The app goes through lifecycle states that need to be handled. Here we add handlers for cancellation and completed states. This state must be declared at the end of the Run method because the event may raise immediately before thread execution continues.

            taskInstance.Task.Completed += TaskCompleted;
            taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled); // event may raise immediately before continuing thread excecution so must be at the end
        }

Task Completed Callback

Because we took a deferral from the task instance during the Run method, we must call Complete on the deferral whenever the task completes. This is the callback method that we registered with the task to handle the Completed notification.


        void TaskCompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
        {
            Debug.WriteLine("MyBackgroundAudioTask " + sender.TaskId + " Completed...");
            deferral.Complete();
        }

Cancellation Callback

The task can be canceled when another media app comes into the foreground and starts playing music, or it can be canceled due to lack of resources if your task consumes more CPU or memory than allowed. If this happens, we save state so that the app can resume gracefully.

Here, we add some handling for the background task being canceled. This handling gives the app time to save state before it closes and resources are reclaimed by the system.


        private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            Debug.WriteLine("MyBackgroundAudioTask " + sender.Task.TaskId + " Cancel Requested...");
            try
            {
                // immediately set not running
                backgroundTaskStarted.Reset();

               ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, GetCurrentTrackId() == null ? null : GetCurrentTrackId().ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.Position, BackgroundMediaPlayer.Current.Position.ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.BackgroundTaskState, BackgroundTaskState.Canceled.ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.AppState, Enum.GetName(typeof(AppState), foregroundAppState));

At this point, we no longer care if any changes are made to the playlist, so we unsubscribe from it.

                if (playbackList != null)
                {
                    playbackList.CurrentItemChanged -= PlaybackList_CurrentItemChanged;
                    playbackList = null;
                }

Similarly, we unsubscribe event handlers. We also call complete on our deferral because we have finished the background work.

                BackgroundMediaPlayer.MessageReceivedFromForeground -= BackgroundMediaPlayer_MessageReceivedFromForeground;
                smtc.ButtonPressed -= smtc_ButtonPressed;
                smtc.PropertyChanged -= smtc_PropertyChanged;
                
                BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            deferral.Complete(); // signals task completion. 
            Debug.WriteLine("MyBackgroundAudioTask Cancel complete...");
        }
        #endregion

Reacting to the SMTC

The audio app should respond to the media controls on the device, such as volume control, pause, stop, back, and skip. This is accomplished through the system media transport controls, which are configured and updated from the background task, not the foreground app.

To set this up, we initialize SystemMediaTransportControls for integration with the Universal Volume Control (UVC). We create a function to update the UVC with playback status and information about the current audio.

        #region SysteMediaTransportControls related functions and handlers
        private void UpdateUVCOnNewTrack(MediaPlaybackItem item)
        {
            if (item == null)
            {
                smtc.PlaybackStatus = MediaPlaybackStatus.Stopped;
                smtc.DisplayUpdater.MusicProperties.Title = string.Empty;
                smtc.DisplayUpdater.Update();
                return;
            }

            smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
            smtc.DisplayUpdater.Type = MediaPlaybackType.Music;
            smtc.DisplayUpdater.MusicProperties.Title = item.Source.CustomProperties[TitleKey] as string;

This code block handles local album art for the display. (Remote URIs are not covered in this sample app.)

            var albumArtUri = item.Source.CustomProperties[AlbumArtKey] as Uri;
            if (albumArtUri != null)
                smtc.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(albumArtUri);
            else
                smtc.DisplayUpdater.Thumbnail = null;

            smtc.DisplayUpdater.Update();
        }

We could optionally add some code to cover what happens if an SMTC property is changed—for example if the sound is muted.

        void smtc_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
        {
           // Put custom code here
    // For example, you could add code to pause the music if the volume is muted
        }

At the very least we need handling for each UVC button: play, pause, next, and previous. The following switch statement is a simple dispatcher that forwards these button presses to one of our class methods that will react to it. Note that if this is not run in the background process, we won’t be able to handle button events when the app is suspended.

Note that the play button presents a special problem. Pressing play could be the event that causes this background process to start running again after being suspended. We’ll wait for the backgroundTaskStarted event to be signaled during our Run method before proceeding so that we know that everything is initialized properly.


        private void smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
        {
            switch (args.Button)
            {

We begin with the play button.

                case SystemMediaTransportControlsButton.Play:
                    Debug.WriteLine("UVC play button pressed");

When the background task has been suspended and the SMTC starts it again asynchronously, time is needed to allow the task startup process in the Run method to complete. The WaitOne method lets the app wait for the task to start. Once it starts, this signal continues until shutdown so that it won’t wait again unless it needs to do so.

                    bool result = backgroundTaskStarted.WaitOne(5000);
                    if (!result)
                        throw new Exception("Background Task didn't initialize in time");
                    
                    StartPlayback();
                    break;

Now the pause button.

                case SystemMediaTransportControlsButton.Pause:
                    Debug.WriteLine("UVC pause button pressed");
                    try
                    {
                        BackgroundMediaPlayer.Current.Pause();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                    break;

And then the next and previous buttons:

                case SystemMediaTransportControlsButton.Next:
                    Debug.WriteLine("UVC next button pressed");
                    SkipToNext();
                    break;
                case SystemMediaTransportControlsButton.Previous:
                    Debug.WriteLine("UVC previous button pressed");
                    SkipToPrevious();
                    break;
            }
        }

        #endregion

Managing playlists

We definitely want our user to be able to play a playlist and navigate through it. We’d also like for playback to resume where the user last stopped when the foreground app closed.

ba_2

A playlist in the desktop version of the sample app.

We set up some playlist management functions and handlers in the following code blocks. In the following code, we try to resume playback from the previously saved track and position.

        #region Playlist management functions and handlers
        /// <summary>
        /// Start playlist and change UVC state
        /// </summary>
        private void StartPlayback()
        {
            try
            {
                // If playback was already started once we can just resume playing.
                if (!playbackStartedPreviously)
                {
                    playbackStartedPreviously = true;

                    // If the task was cancelled we would have saved the current track and its position. We will try playback from there.
                    var currentTrackId = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.TrackId);
                    var currentTrackPosition = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.Position);

And if we have the current track ID, we find the index of the item by name.

                     if (currentTrackId != null)
                    {
                        // Find the index of the item by name
                        var index = playbackList.Items.ToList().FindIndex(item =>
                            GetTrackId(item).ToString() == (string)currentTrackId);

                        if (currentTrackPosition == null)

If there is no saved position for how far into the track to begin, we play it from the beginning.

                        {
                            // Play from start if we dont have position
                            Debug.WriteLine("StartPlayback: Switching to track " + index);
                            playbackList.MoveTo((uint)index);

                            // Begin playing
                            BackgroundMediaPlayer.Current.Play();
                        }

Otherwise, we play it from the saved position in the track.

                        else
                        {
                            // Play from exact position otherwise
                            TypedEventHandler<MediaPlaybackList, CurrentMediaPlaybackItemChangedEventArgs> handler = null;
                            handler = (MediaPlaybackList list, CurrentMediaPlaybackItemChangedEventArgs args) =>
                            {
                                if (args.NewItem == playbackList.Items[index])
                                {

This only needs to run once for this item, so we unsubscribe.

                                    playbackList.CurrentItemChanged -= handler

Then we set the position to start and begin playback.

                                    var position = TimeSpan.Parse((string)currentTrackPosition);
                                    Debug.WriteLine("StartPlayback: Setting Position " + position);
                                    BackgroundMediaPlayer.Current.Position = position;

                                    // Begin playing
                                    BackgroundMediaPlayer.Current.Play();
                                }
                            };

If the user switches the track, we want to trigger an item changed event.

                            playbackList.CurrentItemChanged += handler;

                            // Switch to the track which will trigger an item changed event
                            Debug.WriteLine("StartPlayback: Switching to track " + index);
                            playbackList.MoveTo((uint)index);
                        }
                    }

In case the currentTrackId is null (see ‘currentTrackId != null’ above), we just begin playback without setting a track or position.

                    else
                    {
                        // Begin playing
                        BackgroundMediaPlayer.Current.Play();
                    }
                }

Another else handles playback in the event no playback was previously started (see ‘if (!playbackStartedPreviously’ above).

                else
                {
                    // Begin playing
                    BackgroundMediaPlayer.Current.Play();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }

Next we add some functions to handle navigation through the playlist. We start by getting the new item, then we update the system view (the display), and get the current track.

        void PlaybackList_CurrentItemChanged(MediaPlaybackList sender, CurrentMediaPlaybackItemChangedEventArgs args)
        {
            // Get the new item
            var item = args.NewItem;
            Debug.WriteLine("PlaybackList_CurrentItemChanged: " + (item == null ? "null" : GetTrackId(item).ToString()));

            // Update the system view
            UpdateUVCOnNewTrack(item);

            // Get the current track
            Uri currentTrackId = null;
            if (item != null)
                currentTrackId = item.Source.CustomProperties[TrackIdKey] as Uri;

We also need to notify the foreground app of the change or persist it for later, as shown in the following block.

            if (foregroundAppState == AppState.Active)
                MessageService.SendMessageToForeground(new TrackChangedMessage(currentTrackId));
            else
                ApplicationSettingsHelper.SaveSettingsValue(TrackIdKey, currentTrackId == null ? null : currentTrackId.ToString());
        }

The following code skips playback to the previous track.

        private void SkipToPrevious()
        {
            smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
            playbackList.MovePrevious();

        }

And this skips to the next track.

        private void SkipToNext()
        {
            smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
            playbackList.MoveNext();

            // TODO: Work around playlist bug that doesn't continue playing after a switch; remove later
            BackgroundMediaPlayer.Current.Play();

        }
        #endregion

We will likely want the user to be able to create new playlists, so we add code to handle that. The foreground app creates the playback list by sending it to the background task. Note that this sample does not include a playlist UI.

        #region Background Media Player Handlers
        void CreatePlaybackList(IEnumerable<SongModel> songs)
        {

We begin by making a new list and enabling looping.

            playbackList = new MediaPlaybackList();
            playbackList.AutoRepeatEnabled = true;

Then we add playback items to the list.

            foreach (var song in songs)
            {
                var source = MediaSource.CreateFromUri(song.MediaUri);
                source.CustomProperties[TrackIdKey] = song.MediaUri;
                source.CustomProperties[TitleKey] = song.Title;
                source.CustomProperties[AlbumArtKey] = song.AlbumArtUri;
                playbackList.Items.Add(new MediaPlaybackItem(source));
            }

We want to make sure the new playlist doesn’t automatically start. We assign the list to the media player and add a handler for future playlist item changes.

            BackgroundMediaPlayer.Current.AutoPlay = false;

            // Assign the list to the player
            BackgroundMediaPlayer.Current.Source = playbackList;

            // Add handler for future playlist item changes
            playbackList.CurrentItemChanged += PlaybackList_CurrentItemChanged;
        }

You should be aware that this example demonstrates only how the playlist works with the background media player: MediaPlaybackList is the type of list you would pass into a MediaPlayer. If you would like to explore more ways to work with playlists or creating a playlist UI, it’s worth taking a look at the playlists sample on GitHub and the adaptive streaming sample for streaming audio. The playlists sample shows how you might load a list of songs from a serialized file, a different kind of list that we show here. When deserializing from file, you would still need to add each playback item to a MediaPlaybackList in a way similar to the foreach (var song in songs) statement above.

Communicating with the Background Audio Task

Finally, we create a set of message handlers for the background media player, so the foreground app can send it messages like “App suspending,” “Starting playback,” or “Update playlist.”

void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e)
        {
            AppSuspendedMessage appSuspendedMessage;

The next code block for message handling addresses the app suspending. At this point, the app can save the task state.

            if(MessageService.TryParseMessage(e.Data, out appSuspendedMessage))
            {
                Debug.WriteLine("App suspending"); // App is suspended, you can save your task state at this point
                foregroundAppState = AppState.Suspended;
                var currentTrackId = GetCurrentTrackId();
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, currentTrackId == null ? null : currentTrackId.ToString());
                return;
            }

The following Windows Phone image depicts switching from the background audio sample app to play a song from the SD Card in another app. When this happens, the background audio sample suspends and records the track and position at which playback stopped, so it can start playback from the same place when the app is resumed. Be sure to check out the video near the top of this post to see this in action.

ba_3

In the code below, we handle the messages for the app resuming. When the app is resumed, it subscribes to the message channel.

            AppResumedMessage appResumedMessage;
            if(MessageService.TryParseMessage(e.Data, out appResumedMessage))
            {
                Debug.WriteLine("App resuming"); // App is resumed, now subscribe to message channel
                foregroundAppState = AppState.Active;
                return;
            }

The following code handles messages from the foreground app for starting playback and skipping tracks.


            StartPlaybackMessage startPlaybackMessage;
            if(MessageService.TryParseMessage(e.Data, out startPlaybackMessage))
            {
                //Foreground App process has signalled that it is ready for playback
                Debug.WriteLine("Starting Playback");
                StartPlayback();
                return;
            }

            SkipNextMessage skipNextMessage;
            if(MessageService.TryParseMessage(e.Data, out skipNextMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to next");
                SkipToNext();
                return;
            }

            SkipPreviousMessage skipPreviousMessage;
            if(MessageService.TryParseMessage(e.Data, out skipPreviousMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to previous");
                SkipToPrevious();
                return;
            }

The remaining code in the message handling routine covers changed tracks and updated playlists.

            TrackChangedMessage trackChangedMessage;
            if(MessageService.TryParseMessage(e.Data, out trackChangedMessage))
            {
                var index = playbackList.Items.ToList().FindIndex(i => (Uri)i.Source.CustomProperties[TrackIdKey] == trackChangedMessage.TrackId);
                Debug.WriteLine("Skipping to track " + index);
                smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
                playbackList.MoveTo((uint)index);

                return;
            }

            UpdatePlaylistMessage updatePlaylistMessage;
            if(MessageService.TryParseMessage(e.Data, out updatePlaylistMessage))
            {
                CreatePlaybackList(updatePlaylistMessage.Songs);
                return;
            }
        }

We’ll also need to handle sending the SMTC information on whether the media player is playing, paused, or closed.

        void Current_CurrentStateChanged(MediaPlayer sender, object args)
        {
            if (sender.CurrentState == MediaPlayerState.Playing)
            {
                smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
            }
            else if (sender.CurrentState == MediaPlayerState.Paused)
            {
                smtc.PlaybackStatus = MediaPlaybackStatus.Paused;
            }
            else if (sender.CurrentState == MediaPlayerState.Closed)
            {
                smtc.PlaybackStatus = MediaPlaybackStatus.Closed;
            }
        }
        #endregion
    } //Final curly brace for MyBackgroundAudioTask
} //Final curly brace for BackgroundAudioTask

Wrapping Up

Now that you understand how to utilize background audio, you might like to check out the background audio UWP sample on GitHub. It contains both foreground app and background task sample code, and you can use it as a starting point for your own app. You may also be interested in NPR One’s story about implementing background audio.