<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KAMEGAWA Kazushi</title>
    <description>The latest articles on DEV Community by KAMEGAWA Kazushi (@kkamegawa).</description>
    <link>https://dev.to/kkamegawa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F468624%2F471e4ca1-5e06-48b4-84da-d7bd0f418560.jpeg</url>
      <title>DEV Community: KAMEGAWA Kazushi</title>
      <link>https://dev.to/kkamegawa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kkamegawa"/>
    <language>en</language>
    <item>
      <title>I Built RelayPublisher: A winget-like Publishing Workflow for Microsoft Intune</title>
      <dc:creator>KAMEGAWA Kazushi</dc:creator>
      <pubDate>Tue, 01 Sep 2026 05:09:19 +0000</pubDate>
      <link>https://dev.to/kkamegawa/i-built-relaypublisher-a-winget-like-publishing-workflow-for-microsoft-intune-1oep</link>
      <guid>https://dev.to/kkamegawa/i-built-relaypublisher-a-winget-like-publishing-workflow-for-microsoft-intune-1oep</guid>
      <description>&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Note about this article
&lt;/h2&gt;

&lt;p&gt;The original version of this article was written entirely by me in Japanese.&lt;/p&gt;

&lt;p&gt;I used AI to translate and polish the English version for a global audience, but the ideas, design decisions, implementation details, and original content are all my own work.&lt;/p&gt;

&lt;p&gt;If you'd like to read the original Japanese article, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kkamegawa.hatenablog.jp/entry/2026/08/30/220813" rel="noopener noreferrer"&gt;https://kkamegawa.hatenablog.jp/entry/2026/08/30/220813&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Managing Intune Apps as Code with RelayPublisher
&lt;/h2&gt;

&lt;p&gt;Managing custom applications in Microsoft Intune has always felt more complicated than it should be.&lt;/p&gt;

&lt;p&gt;When you need to publish an internal application, you typically have a few options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register it manually through the Intune portal&lt;/li&gt;
&lt;li&gt;Use one of the sample PowerShell scripts available online&lt;/li&gt;
&lt;li&gt;Build your own automation around Microsoft Graph APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these approaches work, but none of them feel particularly developer-friendly.&lt;/p&gt;

&lt;p&gt;In my case, the process was even more frustrating because I normally don't operate with elevated privileges. Every time I needed to publish or update an application, I had to perform a PIM elevation before making changes.&lt;/p&gt;

&lt;p&gt;That led me to a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why can't Intune application publishing work more like winget?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted a workflow where application definitions could live in source control, be described in YAML, and be published automatically through CI/CD.&lt;/p&gt;

&lt;p&gt;That idea became &lt;strong&gt;RelayPublisher&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/kkamegawa" rel="noopener noreferrer"&gt;
        kkamegawa
      &lt;/a&gt; / &lt;a href="https://github.com/kkamegawa/Relaypublisher" rel="noopener noreferrer"&gt;
        Relaypublisher
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Relaypublisher&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Relaypublisher publishes winget-like YAML manifests as Microsoft Intune LOB apps from CI.&lt;/p&gt;
&lt;p&gt;Distribution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NuGet global tool package id: &lt;code&gt;relaypublisher&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Command name: &lt;code&gt;relaypublisher&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Package version: injected by CI from Git tag &lt;code&gt;vX.Y.Z&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Feeds: nuget.org, GitHub Packages (this repository), and Azure Artifacts&lt;/li&gt;
&lt;li&gt;Self-contained single-file apps for &lt;code&gt;win-x64&lt;/code&gt;, &lt;code&gt;win-arm64&lt;/code&gt;, and &lt;code&gt;osx-arm64&lt;/code&gt; are attached to each
GitHub release. They are neither code-signed nor notarized, so macOS shows a Gatekeeper warning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quick install:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;dotnet tool install --global relaypublisher&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;See &lt;a href="https://github.com/kkamegawa/Relaypublisher/doc/05-operation.md#0-tool-installation-and-version-control" rel="noopener noreferrer"&gt;doc/05-operation.md&lt;/a&gt; for installing
from GitHub Packages or Azure Artifacts instead.&lt;/p&gt;
&lt;p&gt;The repository now contains the .NET CLI foundation for the normal workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;validate&lt;/code&gt; checks manifest schema rules and repository-wide identity uniqueness.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;plan&lt;/code&gt; resolves the target manifest set once and writes &lt;code&gt;manifest-list.json&lt;/code&gt; for later CI jobs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package&lt;/code&gt; stages app files: Windows Win32 &lt;code&gt;.intunewin&lt;/code&gt; packages (Windows runner required) or a
staged, checksum-verified macOS &lt;code&gt;.pkg&lt;/code&gt; (any OS).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;publish&lt;/code&gt; creates or updates Intune apps, uploads packaged content…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kkamegawa/Relaypublisher" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/h2&gt;

&lt;h2&gt;
  
  
  What is RelayPublisher?
&lt;/h2&gt;

&lt;p&gt;RelayPublisher is an open-source tool that allows you to define Intune applications using YAML and publish them through automation.&lt;/p&gt;

&lt;p&gt;Instead of clicking through the Intune portal, you manage application definitions as code.&lt;/p&gt;

&lt;p&gt;If you're already familiar with Infrastructure as Code (IaC) or GitOps practices, the concept should feel natural.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;Historically, building this type of tool felt like a lot of work.&lt;/p&gt;

&lt;p&gt;There are many moving parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Graph integration&lt;/li&gt;
&lt;li&gt;Intune packaging&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Configuration management&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The emergence of generative AI significantly reduced the effort required to create and maintain a project like this. Tasks that would previously have been tedious became much easier to implement.&lt;/p&gt;

&lt;p&gt;As a result, I was finally able to build the tool I had wanted for a long time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;YAML-based application definitions&lt;/li&gt;
&lt;li&gt;CI/CD-friendly workflow&lt;/li&gt;
&lt;li&gt;Microsoft Intune integration&lt;/li&gt;
&lt;li&gt;Source-controlled application management&lt;/li&gt;
&lt;li&gt;Support for GitHub and Azure Repos workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sample YAML definition is included in the repository to help you get started quickly.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;SchemaVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0"&lt;/span&gt;
&lt;span class="na"&gt;PackageIdentifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Microsoft.PowerShell&lt;/span&gt;
&lt;span class="na"&gt;PackageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell&lt;/span&gt;
&lt;span class="na"&gt;Developer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Microsoft Corporation&lt;/span&gt;
&lt;span class="na"&gt;Publisher&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Microsoft Corporation&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell 7 cross-platform automation and configuration tool.&lt;/span&gt;
&lt;span class="na"&gt;PackageVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;7.6.5&lt;/span&gt;
&lt;span class="na"&gt;AssignmentSync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;merge&lt;/span&gt;

&lt;span class="na"&gt;Apps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;macos&lt;/span&gt;
    &lt;span class="na"&gt;Architecture&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
    &lt;span class="na"&gt;InstallerType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pkg&lt;/span&gt;
    &lt;span class="c1"&gt;# pkg (default): unmanaged macOSPkgApp, unsigned allowed, up to 8 GB, and the&lt;/span&gt;
    &lt;span class="c1"&gt;# only AppType that can target MinimumOSVersion 14+ (v14_0/v15_0 are beta-only&lt;/span&gt;
    &lt;span class="c1"&gt;# flags; see doc/01-manifest-schema.md 5.7 and MacOsMinimumOperatingSystemTable).&lt;/span&gt;
    &lt;span class="na"&gt;AppType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pkg&lt;/span&gt;
    &lt;span class="na"&gt;DisplayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell [macOS ARM64]&lt;/span&gt;

    &lt;span class="c1"&gt;# Single Source item for macOS (unified source item shape, doc/01-manifest-schema.md 5.0.1).&lt;/span&gt;
    &lt;span class="c1"&gt;# PowerShell/PowerShell is a public repository, so Auth.Type: none is enough&lt;/span&gt;
    &lt;span class="c1"&gt;# for anonymous asset download.&lt;/span&gt;
    &lt;span class="na"&gt;Source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;githubRelease&lt;/span&gt;
      &lt;span class="na"&gt;Owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell&lt;/span&gt;
      &lt;span class="na"&gt;Repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell&lt;/span&gt;
      &lt;span class="na"&gt;Tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v7.6.5&lt;/span&gt;
      &lt;span class="na"&gt;AssetName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;powershell-7.6.5-osx-arm64.pkg&lt;/span&gt;
      &lt;span class="na"&gt;Destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;powershell-7.6.5-osx-arm64.pkg&lt;/span&gt;
      &lt;span class="na"&gt;Sha256&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;6ea58f4e91ab2df133ac18a42e291e4e870a623e3c5ab6f8368259cd9ac22770"&lt;/span&gt;
      &lt;span class="na"&gt;Auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;

    &lt;span class="na"&gt;Requirements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# PowerShell 7.6 (LTS) supports macOS 14 (Sonoma), 15 (Sequoia), and 26 (Tahoe).&lt;/span&gt;
      &lt;span class="c1"&gt;# 14.0 is the lowest version Relaypublisher's version table can map (26.0 is not&lt;/span&gt;
      &lt;span class="c1"&gt;# yet defined there); AppType: pkg allows the beta-only v14_0 flag.&lt;/span&gt;
      &lt;span class="na"&gt;MinimumOSVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15.0"&lt;/span&gt;

    &lt;span class="na"&gt;Detection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;IgnoreAppVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;IncludedApps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;BundleId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;com.microsoft.powershell&lt;/span&gt;
          &lt;span class="na"&gt;BundleVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;7.6.5&lt;/span&gt;

    &lt;span class="c1"&gt;# Optional, AppType: pkg only (doc/01-manifest-schema.md §5.4.2): pre/post-install&lt;/span&gt;
    &lt;span class="c1"&gt;# shell scripts, mapped to Graph macOSPkgApp.preInstallScript/postInstallScript.&lt;/span&gt;
    &lt;span class="c1"&gt;# Paths are relative to --repo-root (samples/, per this file's own README).&lt;/span&gt;
    &lt;span class="na"&gt;Scripts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;PreInstall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/macos/powershell/preinstall.sh&lt;/span&gt;
      &lt;span class="na"&gt;PostInstall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/macos/powershell/postinstall.sh&lt;/span&gt;

    &lt;span class="c1"&gt;# Left empty so this manifest applies unmodified in any tenant. Add your own&lt;/span&gt;
    &lt;span class="c1"&gt;# target group(s) before a real (non-dry-run) publish, for example:&lt;/span&gt;
    &lt;span class="c1"&gt;# Assignments:&lt;/span&gt;
    &lt;span class="c1"&gt;#   - Target: group&lt;/span&gt;
    &lt;span class="c1"&gt;#     GroupId: "&amp;lt;your-assignment-group-guid&amp;gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;#     Intent: required&lt;/span&gt;
    &lt;span class="na"&gt;Assignments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>opensource</category>
      <category>dotnet</category>
      <category>microsoft</category>
      <category>intune</category>
    </item>
    <item>
      <title>Visual Studio 2022 Memory Eater Extension</title>
      <dc:creator>KAMEGAWA Kazushi</dc:creator>
      <pubDate>Fri, 18 Jun 2021 11:19:02 +0000</pubDate>
      <link>https://dev.to/kkamegawa/visual-studio-2022-memory-eater-extension-4iem</link>
      <guid>https://dev.to/kkamegawa/visual-studio-2022-memory-eater-extension-4iem</guid>
      <description>&lt;p&gt;I had just published simple extension for Visual Studio 2022 Preview 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kkamegawa/memoryeaterextension"&gt;GitHub/kkamegawa/memoryeaterextension&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yC5_qQds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aq1zophdaha135gvfq4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yC5_qQds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aq1zophdaha135gvfq4y.png" alt="Over 2GB use in Visual Studio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This extension will not publish to marketplace. &lt;/p&gt;

&lt;p&gt;It's simple memory eater extension :-).&lt;/p&gt;

</description>
      <category>visualstudio</category>
    </item>
  </channel>
</rss>
